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