ril.cpp revision a8657f8726ba81b72eb532c884545b4ad52ff471
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
1223/**
1224 * A write on the wakeup fd is done just to pop us out of select()
1225 * We empty the buffer here and then ril_event will reset the timers on the
1226 * way back down
1227 */
1228static void processWakeupCallback(int fd, short flags, void *param)
1229{
1230    char buff[16];
1231    int ret;
1232
1233    LOGV("processWakeupCallback");
1234
1235    /* empty our wakeup socket out */
1236    do {
1237        ret = read(s_fdWakeupRead, &buff, sizeof(buff));
1238    } while (ret > 0 || (ret < 0 && errno == EINTR));
1239}
1240
1241static void onCommandsSocketClosed()
1242{
1243    int ret;
1244    RequestInfo *p_cur;
1245
1246    /* mark pending requests as "cancelled" so we dont report responses */
1247
1248    ret = pthread_mutex_lock(&s_pendingRequestsMutex);
1249    assert (ret == 0);
1250
1251    p_cur = s_pendingRequests;
1252
1253    for (p_cur = s_pendingRequests
1254            ; p_cur != NULL
1255            ; p_cur  = p_cur->p_next
1256    ) {
1257        p_cur->cancelled = 1;
1258    }
1259
1260    ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
1261    assert (ret == 0);
1262}
1263
1264static void processCommandsCallback(int fd, short flags, void *param)
1265{
1266    RecordStream *p_rs;
1267    void *p_record;
1268    size_t recordlen;
1269    int ret;
1270
1271    assert(fd == s_fdCommand);
1272
1273    p_rs = (RecordStream *)param;
1274
1275    for (;;) {
1276        /* loop until EAGAIN/EINTR, end of stream, or other error */
1277        ret = record_stream_get_next(p_rs, &p_record, &recordlen);
1278
1279        if (ret == 0 && p_record == NULL) {
1280            /* end-of-stream */
1281            break;
1282        } else if (ret < 0) {
1283            break;
1284        } else if (ret == 0) { /* && p_record != NULL */
1285            processCommandBuffer(p_record, recordlen);
1286        }
1287    }
1288
1289    if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) {
1290        /* fatal error or end-of-stream */
1291        if (ret != 0) {
1292            LOGE("error on reading command socket errno:%d\n", errno);
1293        } else {
1294            LOGW("EOS.  Closing command socket.");
1295        }
1296
1297        close(s_fdCommand);
1298        s_fdCommand = -1;
1299
1300        ril_event_del(&s_commands_event);
1301
1302        record_stream_free(p_rs);
1303
1304        /* start listening for new connections again */
1305        ril_event_add(&s_listen_event);
1306
1307        onCommandsSocketClosed();
1308    }
1309}
1310
1311
1312static void onNewCommandConnect()
1313{
1314    // implicit radio state changed
1315    RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
1316                                    NULL, 0);
1317
1318    // Send last NITZ time data, in case it was missed
1319    if (s_lastNITZTimeData != NULL) {
1320        sendResponseRaw(s_lastNITZTimeData, s_lastNITZTimeDataSize);
1321
1322        free(s_lastNITZTimeData);
1323        s_lastNITZTimeData = NULL;
1324    }
1325
1326    // Get version string
1327    if (s_callbacks.getVersion != NULL) {
1328        const char *version;
1329        version = s_callbacks.getVersion();
1330        LOGI("RIL Daemon version: %s\n", version);
1331
1332        property_set(PROPERTY_RIL_IMPL, version);
1333    } else {
1334        LOGI("RIL Daemon version: unavailable\n");
1335        property_set(PROPERTY_RIL_IMPL, "unavailable");
1336    }
1337
1338}
1339
1340static void listenCallback (int fd, short flags, void *param)
1341{
1342    int ret;
1343    int err;
1344    int is_phone_socket;
1345    RecordStream *p_rs;
1346
1347    struct sockaddr_un peeraddr;
1348    socklen_t socklen = sizeof (peeraddr);
1349
1350    struct ucred creds;
1351    socklen_t szCreds = sizeof(creds);
1352
1353    struct passwd *pwd = NULL;
1354
1355    assert (s_fdCommand < 0);
1356    assert (fd == s_fdListen);
1357
1358    s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);
1359
1360    if (s_fdCommand < 0 ) {
1361        LOGE("Error on accept() errno:%d", errno);
1362        /* start listening for new connections again */
1363        ril_event_add(&s_listen_event);
1364	return;
1365    }
1366
1367    /* check the credential of the other side and only accept socket from
1368     * phone process
1369     */
1370    errno = 0;
1371    is_phone_socket = 0;
1372
1373    err = getsockopt(s_fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds);
1374
1375    if (err == 0 && szCreds > 0) {
1376      errno = 0;
1377      pwd = getpwuid(creds.uid);
1378      if (pwd != NULL) {
1379	if (strcmp(pwd->pw_name, PHONE_PROCESS) == 0) {
1380	  is_phone_socket = 1;
1381	} else {
1382	  LOGE("RILD can't accept socket from process %s", pwd->pw_name);
1383	}
1384      } else {
1385	LOGE("Error on getpwuid() errno: %d", errno);
1386      }
1387    } else {
1388      LOGD("Error on getsockopt() errno: %d", errno);
1389    }
1390
1391    if ( !is_phone_socket ) {
1392      LOGE("RILD must accept socket from %s", PHONE_PROCESS);
1393
1394      close(s_fdCommand);
1395      s_fdCommand = -1;
1396
1397      onCommandsSocketClosed();
1398
1399      /* start listening for new connections again */
1400      ril_event_add(&s_listen_event);
1401
1402      return;
1403    }
1404
1405    ret = fcntl(s_fdCommand, F_SETFL, O_NONBLOCK);
1406
1407    if (ret < 0) {
1408        LOGE ("Error setting O_NONBLOCK errno:%d", errno);
1409    }
1410
1411    LOGI("libril: new connection");
1412
1413    p_rs = record_stream_new(s_fdCommand, MAX_COMMAND_BYTES);
1414
1415    ril_event_set (&s_commands_event, s_fdCommand, 1,
1416        processCommandsCallback, p_rs);
1417
1418    ril_event_add (&s_commands_event);
1419
1420    onNewCommandConnect();
1421}
1422
1423static void freeDebugCallbackArgs(int number, char **args) {
1424    for (int i = 0; i < number; i++) {
1425        if (args[i] != NULL) {
1426            free(args[i]);
1427        }
1428    }
1429    free(args);
1430}
1431
1432static void debugCallback (int fd, short flags, void *param)
1433{
1434    int acceptFD, option;
1435    struct sockaddr_un peeraddr;
1436    socklen_t socklen = sizeof (peeraddr);
1437    int data;
1438    unsigned int qxdm_data[6];
1439    const char *deactData[1] = {"1"};
1440    char *actData[1];
1441    RIL_Dial dialData;
1442    int hangupData[1] = {1};
1443    int number;
1444    char **args;
1445
1446    acceptFD = accept (fd,  (sockaddr *) &peeraddr, &socklen);
1447
1448    if (acceptFD < 0) {
1449        LOGE ("error accepting on debug port: %d\n", errno);
1450        return;
1451    }
1452
1453    if (recv(acceptFD, &number, sizeof(int), 0) != sizeof(int)) {
1454        LOGE ("error reading on socket: number of Args: \n");
1455        return;
1456    }
1457    args = (char **) malloc(sizeof(char*) * number);
1458
1459    for (int i = 0; i < number; i++) {
1460        int len;
1461        if (recv(acceptFD, &len, sizeof(int), 0) != sizeof(int)) {
1462            LOGE ("error reading on socket: Len of Args: \n");
1463            freeDebugCallbackArgs(i, args);
1464            return;
1465        }
1466        // +1 for null-term
1467        args[i] = (char *) malloc((sizeof(char) * len) + 1);
1468        if (recv(acceptFD, args[i], sizeof(char) * len, 0)
1469            != sizeof(char) * len) {
1470            LOGE ("error reading on socket: Args[%d] \n", i);
1471            freeDebugCallbackArgs(i, args);
1472            return;
1473        }
1474        char * buf = args[i];
1475        buf[len] = 0;
1476    }
1477
1478    switch (atoi(args[0])) {
1479        case 0:
1480            LOGI ("Connection on debug port: issuing reset.");
1481            issueLocalRequest(RIL_REQUEST_RESET_RADIO, NULL, 0);
1482            break;
1483        case 1:
1484            LOGI ("Connection on debug port: issuing radio power off.");
1485            data = 0;
1486            issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int));
1487            // Close the socket
1488            close(s_fdCommand);
1489            s_fdCommand = -1;
1490            break;
1491        case 2:
1492            LOGI ("Debug port: issuing unsolicited network change.");
1493            RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED,
1494                                      NULL, 0);
1495            break;
1496        case 3:
1497            LOGI ("Debug port: QXDM log enable.");
1498            qxdm_data[0] = 65536;
1499            qxdm_data[1] = 16;
1500            qxdm_data[2] = 1;
1501            qxdm_data[3] = 32;
1502            qxdm_data[4] = 0;
1503            qxdm_data[4] = 8;
1504            issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
1505                              6 * sizeof(int));
1506            break;
1507        case 4:
1508            LOGI ("Debug port: QXDM log disable.");
1509            qxdm_data[0] = 65536;
1510            qxdm_data[1] = 16;
1511            qxdm_data[2] = 0;
1512            qxdm_data[3] = 32;
1513            qxdm_data[4] = 0;
1514            qxdm_data[4] = 8;
1515            issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
1516                              6 * sizeof(int));
1517            break;
1518        case 5:
1519            LOGI("Debug port: Radio On");
1520            data = 1;
1521            issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int));
1522            sleep(2);
1523            // Set network selection automatic.
1524            issueLocalRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, NULL, 0);
1525            break;
1526        case 6:
1527            LOGI("Debug port: Setup PDP, Apn :%s\n", args[1]);
1528            actData[0] = args[1];
1529            issueLocalRequest(RIL_REQUEST_SETUP_DEFAULT_PDP, &actData,
1530                              sizeof(actData));
1531            break;
1532        case 7:
1533            LOGI("Debug port: Deactivate PDP");
1534            issueLocalRequest(RIL_REQUEST_DEACTIVATE_DEFAULT_PDP, &deactData,
1535                              sizeof(deactData));
1536            break;
1537        case 8:
1538            LOGI("Debug port: Dial Call");
1539            dialData.clir = 0;
1540            dialData.address = args[1];
1541            issueLocalRequest(RIL_REQUEST_DIAL, &dialData, sizeof(dialData));
1542            break;
1543        case 9:
1544            LOGI("Debug port: Answer Call");
1545            issueLocalRequest(RIL_REQUEST_ANSWER, NULL, 0);
1546            break;
1547        case 10:
1548            LOGI("Debug port: End Call");
1549            issueLocalRequest(RIL_REQUEST_HANGUP, &hangupData,
1550                              sizeof(hangupData));
1551            break;
1552        default:
1553            LOGE ("Invalid request");
1554            break;
1555    }
1556    freeDebugCallbackArgs(number, args);
1557    close(acceptFD);
1558}
1559
1560
1561static void userTimerCallback (int fd, short flags, void *param)
1562{
1563    UserCallbackInfo *p_info;
1564
1565    p_info = (UserCallbackInfo *)param;
1566
1567    p_info->p_callback(p_info->userParam);
1568
1569
1570    // FIXME generalize this...there should be a cancel mechanism
1571    if (s_last_wake_timeout_info != NULL && s_last_wake_timeout_info == p_info) {
1572        s_last_wake_timeout_info = NULL;
1573    }
1574
1575    free(p_info);
1576}
1577
1578
1579static void *
1580eventLoop(void *param)
1581{
1582    int ret;
1583    int filedes[2];
1584
1585    ril_event_init();
1586
1587    pthread_mutex_lock(&s_startupMutex);
1588
1589    s_started = 1;
1590    pthread_cond_broadcast(&s_startupCond);
1591
1592    pthread_mutex_unlock(&s_startupMutex);
1593
1594    ret = pipe(filedes);
1595
1596    if (ret < 0) {
1597        LOGE("Error in pipe() errno:%d", errno);
1598        return NULL;
1599    }
1600
1601    s_fdWakeupRead = filedes[0];
1602    s_fdWakeupWrite = filedes[1];
1603
1604    fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
1605
1606    ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
1607                processWakeupCallback, NULL);
1608
1609    ril_event_add (&s_wakeupfd_event);
1610
1611    // Only returns on error
1612    ril_event_loop();
1613    LOGE ("error in event_loop_base errno:%d", errno);
1614
1615    return NULL;
1616}
1617
1618extern "C" void
1619RIL_startEventLoop(void)
1620{
1621    int ret;
1622    pthread_attr_t attr;
1623
1624    /* spin up eventLoop thread and wait for it to get started */
1625    s_started = 0;
1626    pthread_mutex_lock(&s_startupMutex);
1627
1628    pthread_attr_init (&attr);
1629    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1630    ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
1631
1632    while (s_started == 0) {
1633        pthread_cond_wait(&s_startupCond, &s_startupMutex);
1634    }
1635
1636    pthread_mutex_unlock(&s_startupMutex);
1637
1638    if (ret < 0) {
1639        LOGE("Failed to create dispatch thread errno:%d", errno);
1640        return;
1641    }
1642}
1643
1644// Used for testing purpose only.
1645extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) {
1646    memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
1647}
1648
1649extern "C" void
1650RIL_register (const RIL_RadioFunctions *callbacks)
1651{
1652    int ret;
1653    int flags;
1654
1655    if (callbacks == NULL
1656        || ! (callbacks->version == RIL_VERSION || callbacks->version == 1)
1657    ) {
1658        LOGE(
1659            "RIL_register: RIL_RadioFunctions * null or invalid version"
1660            " (expected %d)", RIL_VERSION);
1661        return;
1662    }
1663
1664    if (s_registerCalled > 0) {
1665        LOGE("RIL_register has been called more than once. "
1666                "Subsequent call ignored");
1667        return;
1668    }
1669
1670    memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
1671
1672    s_registerCalled = 1;
1673
1674    // Little self-check
1675
1676    for (int i = 0; i < (int)NUM_ELEMS(s_commands) ; i++) {
1677        assert(i == s_commands[i].requestNumber);
1678    }
1679
1680    for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses) ; i++) {
1681        assert(i + RIL_UNSOL_RESPONSE_BASE
1682                == s_unsolResponses[i].requestNumber);
1683    }
1684
1685    // New rild impl calls RIL_startEventLoop() first
1686    // old standalone impl wants it here.
1687
1688    if (s_started == 0) {
1689        RIL_startEventLoop();
1690    }
1691
1692    // start listen socket
1693
1694#if 0
1695    ret = socket_local_server (SOCKET_NAME_RIL,
1696            ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
1697
1698    if (ret < 0) {
1699        LOGE("Unable to bind socket errno:%d", errno);
1700        exit (-1);
1701    }
1702    s_fdListen = ret;
1703
1704#else
1705    s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);
1706    if (s_fdListen < 0) {
1707        LOGE("Failed to get socket '" SOCKET_NAME_RIL "'");
1708        exit(-1);
1709    }
1710
1711    ret = listen(s_fdListen, 4);
1712
1713    if (ret < 0) {
1714        LOGE("Failed to listen on control socket '%d': %s",
1715             s_fdListen, strerror(errno));
1716        exit(-1);
1717    }
1718#endif
1719
1720
1721    /* note: non-persistent so we can accept only one connection at a time */
1722    ril_event_set (&s_listen_event, s_fdListen, false,
1723                listenCallback, NULL);
1724
1725    ril_event_add (&s_listen_event);
1726
1727#if 1
1728    // start debug interface socket
1729
1730    s_fdDebug = android_get_control_socket(SOCKET_NAME_RIL_DEBUG);
1731    if (s_fdDebug < 0) {
1732        LOGE("Failed to get socket '" SOCKET_NAME_RIL_DEBUG "' errno:%d", errno);
1733        exit(-1);
1734    }
1735
1736    ret = listen(s_fdDebug, 4);
1737
1738    if (ret < 0) {
1739        LOGE("Failed to listen on ril debug socket '%d': %s",
1740             s_fdDebug, strerror(errno));
1741        exit(-1);
1742    }
1743
1744    ril_event_set (&s_debug_event, s_fdDebug, true,
1745                debugCallback, NULL);
1746
1747    ril_event_add (&s_debug_event);
1748#endif
1749
1750}
1751
1752static int
1753checkAndDequeueRequestInfo(struct RequestInfo *pRI)
1754{
1755    int ret = 0;
1756
1757    if (pRI == NULL) {
1758        return 0;
1759    }
1760
1761    pthread_mutex_lock(&s_pendingRequestsMutex);
1762
1763    for(RequestInfo **ppCur = &s_pendingRequests
1764        ; *ppCur != NULL
1765        ; ppCur = &((*ppCur)->p_next)
1766    ) {
1767        if (pRI == *ppCur) {
1768            ret = 1;
1769
1770            *ppCur = (*ppCur)->p_next;
1771            break;
1772        }
1773    }
1774
1775    pthread_mutex_unlock(&s_pendingRequestsMutex);
1776
1777    return ret;
1778}
1779
1780
1781extern "C" void
1782RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen)
1783{
1784    RequestInfo *pRI;
1785    int ret;
1786    size_t errorOffset;
1787
1788    pRI = (RequestInfo *)t;
1789
1790    if (!checkAndDequeueRequestInfo(pRI)) {
1791        LOGE ("RIL_onRequestComplete: invalid RIL_Token");
1792        return;
1793    }
1794
1795    if (pRI->local > 0) {
1796        // Locally issued command...void only!
1797        // response does not go back up the command socket
1798        LOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
1799
1800        goto done;
1801    }
1802
1803    appendPrintBuf("[%04d]< %s",
1804        pRI->token, requestToString(pRI->pCI->requestNumber));
1805
1806    if (pRI->cancelled == 0) {
1807        Parcel p;
1808
1809        p.writeInt32 (RESPONSE_SOLICITED);
1810        p.writeInt32 (pRI->token);
1811        errorOffset = p.dataPosition();
1812
1813        p.writeInt32 (e);
1814
1815        if (e == RIL_E_SUCCESS) {
1816            /* process response on success */
1817            ret = pRI->pCI->responseFunction(p, response, responselen);
1818
1819            /* if an error occurred, rewind and mark it */
1820            if (ret != 0) {
1821                p.setDataPosition(errorOffset);
1822                p.writeInt32 (ret);
1823            }
1824        } else {
1825            appendPrintBuf("%s returns %s", printBuf, failCauseToString(e));
1826        }
1827
1828        if (s_fdCommand < 0) {
1829            LOGD ("RIL onRequestComplete: Command channel closed");
1830        }
1831        sendResponse(p);
1832    }
1833
1834done:
1835    free(pRI);
1836}
1837
1838
1839static void
1840grabFullWakeLock()
1841{
1842    int fd;
1843
1844    fd = open (ANDROID_FULL_WAKE_LOCK_PATH, O_WRONLY);
1845
1846    if (fd < 0) {
1847        LOGW ("Cannot open " ANDROID_FULL_WAKE_LOCK_PATH);
1848        return;
1849    }
1850
1851    write (fd, ANDROID_WAKE_LOCK_NAME, strlen(ANDROID_WAKE_LOCK_NAME));
1852    close (fd);
1853}
1854
1855static void
1856grabPartialWakeLock()
1857{
1858    int fd;
1859
1860    fd = open (ANDROID_PARTIAL_WAKE_LOCK_PATH, O_WRONLY);
1861
1862    if (fd < 0) {
1863        LOGW ("Cannot open " ANDROID_PARTIAL_WAKE_LOCK_PATH);
1864        return;
1865    }
1866
1867    write (fd, ANDROID_WAKE_LOCK_NAME, strlen(ANDROID_WAKE_LOCK_NAME));
1868    close (fd);
1869}
1870
1871static void
1872releaseWakeLock()
1873{
1874    int fd;
1875
1876    fd = open (ANDROID_WAKE_UNLOCK_PATH, O_WRONLY);
1877
1878    if (fd < 0) {
1879        LOGW ("Cannot open " ANDROID_WAKE_UNLOCK_PATH);
1880        return;
1881    }
1882
1883    write (fd, ANDROID_WAKE_LOCK_NAME, strlen(ANDROID_WAKE_LOCK_NAME));
1884    close (fd);
1885}
1886
1887/**
1888 * Timer callback to put us back to sleep before the default timeout
1889 */
1890static void
1891wakeTimeoutCallback (void *param)
1892{
1893    // We're using "param != NULL" as a cancellation mechanism
1894    if (param == NULL) {
1895        //LOGD("wakeTimeout: releasing wake lock");
1896
1897        releaseWakeLock();
1898    } else {
1899        //LOGD("wakeTimeout: releasing wake lock CANCELLED");
1900    }
1901}
1902
1903extern "C"
1904void RIL_onUnsolicitedResponse(int unsolResponse, void *data,
1905                                size_t datalen)
1906{
1907    int unsolResponseIndex;
1908    int ret;
1909
1910    if (s_registerCalled == 0) {
1911        // Ignore RIL_onUnsolicitedResponse before RIL_register
1912        LOGW("RIL_onUnsolicitedResponse called before RIL_register");
1913        return;
1914    }
1915
1916    unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
1917
1918    if (unsolResponseIndex < 0
1919        || unsolResponseIndex >= (int32_t)NUM_ELEMS(s_unsolResponses)) {
1920        LOGE("unsupported unsolicited response code %d", unsolResponse);
1921        return;
1922    }
1923
1924    appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
1925
1926    Parcel p;
1927
1928    p.writeInt32 (RESPONSE_UNSOLICITED);
1929    p.writeInt32 (unsolResponse);
1930
1931    ret = s_unsolResponses[unsolResponseIndex]
1932                .responseFunction(p, data, datalen);
1933
1934    // some things get more payload
1935    switch(unsolResponse) {
1936        case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
1937            p.writeInt32(s_callbacks.onStateRequest());
1938            appendPrintBuf("%s {%s}", printBuf,
1939                radioStateToString(s_callbacks.onStateRequest()));
1940        break;
1941
1942
1943        case RIL_UNSOL_NITZ_TIME_RECEIVED:
1944            int64_t timeReceived = elapsedRealtime();
1945            // Store the time this was received in case it is delayed
1946            p.writeInt64(timeReceived);
1947        break;
1948    }
1949
1950    if (ret != 0) {
1951        // Problem with the response. Don't continue;
1952        return;
1953    }
1954
1955
1956    ret = sendResponse(p);
1957
1958    if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
1959
1960        // Unfortunately, NITZ time is not poll/update like everything
1961        // else in the system. So, if the upstream client isn't connected,
1962        // keep a copy of the last NITZ response (with receive time noted
1963        // above) around so we can deliver it when it is connected
1964
1965        if (s_lastNITZTimeData != NULL) {
1966            free (s_lastNITZTimeData);
1967            s_lastNITZTimeData = NULL;
1968        }
1969
1970        s_lastNITZTimeData = malloc(p.dataSize());
1971        s_lastNITZTimeDataSize = p.dataSize();
1972        memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
1973    }
1974
1975    bool shouldScheduleTimeout = false;
1976
1977    switch (s_unsolResponses[unsolResponseIndex].wakeType) {
1978        case WAKE_PARTIAL:
1979            grabPartialWakeLock();
1980            shouldScheduleTimeout = true;
1981        break;
1982
1983        case WAKE_FULL:
1984            grabFullWakeLock();
1985            shouldScheduleTimeout = true;
1986        break;
1987
1988        case DONT_WAKE:
1989        default:
1990            break;
1991    }
1992
1993    // For now, we automatically go back to sleep after TIMEVAL_WAKE_TIMEOUT
1994    // FIXME The java code should handshake here to release wake lock
1995
1996    if (shouldScheduleTimeout) {
1997        // Cancel the previous request
1998        if (s_last_wake_timeout_info != NULL) {
1999            s_last_wake_timeout_info->userParam = (void *)1;
2000        }
2001
2002        s_last_wake_timeout_info
2003            = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
2004                                            &TIMEVAL_WAKE_TIMEOUT);
2005    }
2006}
2007
2008/** FIXME generalize this if you track UserCAllbackInfo, clear it
2009    when the callback occurs
2010*/
2011static UserCallbackInfo *
2012internalRequestTimedCallback (RIL_TimedCallback callback, void *param,
2013                                const struct timeval *relativeTime)
2014
2015{
2016    struct timeval myRelativeTime;
2017    UserCallbackInfo *p_info;
2018    int ret;
2019
2020    p_info = (UserCallbackInfo *) malloc (sizeof(UserCallbackInfo));
2021
2022    p_info->p_callback = callback;
2023    p_info->userParam = param;
2024
2025    if (relativeTime == NULL) {
2026        /* treat null parameter as a 0 relative time */
2027        memset (&myRelativeTime, 0, sizeof(myRelativeTime));
2028    } else {
2029        /* FIXME I think event_add's tv param is really const anyway */
2030        memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime));
2031    }
2032
2033    ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info);
2034
2035    ril_timer_add(&(p_info->event), &myRelativeTime);
2036
2037    if (!pthread_equal(pthread_self(), s_tid_dispatch)) {
2038        /* trigger event loop to wakeup
2039           No reason to to this if we're in the event loop thread */
2040        do {
2041            ret = write (s_fdWakeupWrite, " ", 1);
2042        } while (ret < 0 && errno == EINTR);
2043    }
2044
2045    return p_info;
2046}
2047
2048
2049extern "C" void
2050RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
2051                                const struct timeval *relativeTime)
2052{
2053    internalRequestTimedCallback (callback, param, relativeTime);
2054}
2055
2056const char *
2057failCauseToString(RIL_Errno e)
2058{
2059    switch(e) {
2060        case RIL_E_SUCCESS: return "E_SUCCESS";
2061        case RIL_E_RADIO_NOT_AVAILABLE: return "E_RAIDO_NOT_AVAILABLE";
2062        case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE";
2063        case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT";
2064        case RIL_E_SIM_PIN2: return "E_SIM_PIN2";
2065        case RIL_E_SIM_PUK2: return "E_SIM_PUK2";
2066        case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED";
2067        case RIL_E_CANCELLED: return "E_CANCELLED";
2068        case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL";
2069        case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW";
2070        case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY";
2071        default: return "<unknown error>";
2072    }
2073}
2074
2075const char *
2076radioStateToString(RIL_RadioState s)
2077{
2078    switch(s) {
2079        case RADIO_STATE_OFF: return "RADIO_OFF";
2080        case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE";
2081        case RADIO_STATE_SIM_NOT_READY: return "RADIO_SIM_NOT_READY";
2082        case RADIO_STATE_SIM_LOCKED_OR_ABSENT: return "RADIO_SIM_LOCKED_OR_ABSENT";
2083        case RADIO_STATE_SIM_READY: return "RADIO_SIM_READY";
2084        default: return "<unknown state>";
2085    }
2086}
2087
2088const char *
2089callStateToString(RIL_CallState s)
2090{
2091    switch(s) {
2092        case RIL_CALL_ACTIVE : return "ACTIVE";
2093        case RIL_CALL_HOLDING: return "HOLDING";
2094        case RIL_CALL_DIALING: return "DIALING";
2095        case RIL_CALL_ALERTING: return "ALERTING";
2096        case RIL_CALL_INCOMING: return "INCOMING";
2097        case RIL_CALL_WAITING: return "WAITING";
2098        default: return "<unknown state>";
2099    }
2100}
2101
2102const char *
2103requestToString(int request)
2104{
2105/*
2106 cat libs/telephony/ril_commands.h \
2107 | egrep "^ *{RIL_" \
2108 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
2109
2110
2111 cat libs/telephony/ril_unsol_commands.h \
2112 | egrep "^ *{RIL_" \
2113 | sed -re 's/\{RIL_([^,]+),([^}]+).+/case RIL_\1: return "\1";/'
2114
2115*/
2116    switch(request) {
2117        case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
2118        case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
2119        case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
2120        case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
2121        case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
2122        case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
2123        case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
2124        case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
2125        case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
2126        case RIL_REQUEST_DIAL: return "DIAL";
2127        case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
2128        case RIL_REQUEST_HANGUP: return "HANGUP";
2129        case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
2130        case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
2131        case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
2132        case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
2133        case RIL_REQUEST_UDUB: return "UDUB";
2134        case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
2135        case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
2136        case RIL_REQUEST_REGISTRATION_STATE: return "REGISTRATION_STATE";
2137        case RIL_REQUEST_GPRS_REGISTRATION_STATE: return "GPRS_REGISTRATION_STATE";
2138        case RIL_REQUEST_OPERATOR: return "OPERATOR";
2139        case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
2140        case RIL_REQUEST_DTMF: return "DTMF";
2141        case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
2142        case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
2143        case RIL_REQUEST_SETUP_DEFAULT_PDP: return "SETUP_DEFAULT_PDP";
2144        case RIL_REQUEST_SIM_IO: return "SIM_IO";
2145        case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
2146        case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
2147        case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
2148        case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
2149        case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
2150        case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
2151        case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
2152        case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
2153        case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
2154        case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
2155        case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
2156        case RIL_REQUEST_ANSWER: return "ANSWER";
2157        case RIL_REQUEST_DEACTIVATE_DEFAULT_PDP: return "DEACTIVATE_DEFAULT_PDP";
2158        case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
2159        case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
2160        case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
2161        case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
2162        case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
2163        case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
2164        case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
2165        case RIL_REQUEST_DTMF_START: return "DTMF_START";
2166        case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
2167        case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
2168        case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
2169        case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE";
2170        case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE";
2171        case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS";
2172        case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
2173        case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
2174        case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
2175        case RIL_REQUEST_LAST_PDP_FAIL_CAUSE: return "LAST_PDP_FAIL_CAUSE";
2176        case RIL_REQUEST_PDP_CONTEXT_LIST: return "PDP_CONTEXT_LIST";
2177        case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
2178        case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
2179        case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
2180	    case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
2181	    case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
2182        case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE";
2183        case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE";
2184        case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND";
2185        case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE";
2186        case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
2187        case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
2188        case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER";
2189        case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES";
2190
2191        case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
2192        case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
2193        case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_NETWORK_STATE_CHANGED";
2194        case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
2195        case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
2196        case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
2197        case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
2198        case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
2199        case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
2200        case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
2201        case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
2202        case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
2203        case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
2204        case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
2205        case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FUL";
2206        case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
2207        case RIL_UNSOL_PDP_CONTEXT_LIST_CHANGED: return "UNSOL_PDP_CONTEXT_LIST_CHANGED";
2208        case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
2209        default: return "<unknown request>";
2210    }
2211}
2212
2213} /* namespace android */
2214