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#include <telephony/ril.h>
22#include <telephony/ril_cdma_sms.h>
23#include <cutils/sockets.h>
24#include <cutils/jstring.h>
25#include <telephony/record_stream.h>
26#include <utils/Log.h>
27#include <utils/SystemClock.h>
28#include <pthread.h>
29#include <binder/Parcel.h>
30#include <cutils/jstring.h>
31#include <sys/types.h>
32#include <sys/limits.h>
33#include <sys/system_properties.h>
34#include <pwd.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <stdarg.h>
38#include <string.h>
39#include <unistd.h>
40#include <fcntl.h>
41#include <time.h>
42#include <errno.h>
43#include <assert.h>
44#include <ctype.h>
45#include <sys/un.h>
46#include <assert.h>
47#include <netinet/in.h>
48#include <cutils/properties.h>
49#include <RilSapSocket.h>
50
51extern "C" void
52RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen);
53
54extern "C" void
55RIL_onRequestAck(RIL_Token t);
56namespace android {
57
58#define PHONE_PROCESS "radio"
59#define BLUETOOTH_PROCESS "bluetooth"
60
61#define SOCKET_NAME_RIL "rild"
62#define SOCKET2_NAME_RIL "rild2"
63#define SOCKET3_NAME_RIL "rild3"
64#define SOCKET4_NAME_RIL "rild4"
65
66#define SOCKET_NAME_RIL_DEBUG "rild-debug"
67
68#define ANDROID_WAKE_LOCK_NAME "radio-interface"
69
70#define ANDROID_WAKE_LOCK_SECS 0
71#define ANDROID_WAKE_LOCK_USECS 200000
72
73#define PROPERTY_RIL_IMPL "gsm.version.ril-impl"
74
75// match with constant in RIL.java
76#define MAX_COMMAND_BYTES (8 * 1024)
77
78// Basically: memset buffers that the client library
79// shouldn't be using anymore in an attempt to find
80// memory usage issues sooner.
81#define MEMSET_FREED 1
82
83#define NUM_ELEMS(a)     (sizeof (a) / sizeof (a)[0])
84
85#define MIN(a,b) ((a)<(b) ? (a) : (b))
86
87/* Constants for response types */
88#define RESPONSE_SOLICITED 0
89#define RESPONSE_UNSOLICITED 1
90#define RESPONSE_SOLICITED_ACK 2
91#define RESPONSE_SOLICITED_ACK_EXP 3
92#define RESPONSE_UNSOLICITED_ACK_EXP 4
93
94/* Negative values for private RIL errno's */
95#define RIL_ERRNO_INVALID_RESPONSE -1
96#define RIL_ERRNO_NO_MEMORY -12
97
98// request, response, and unsolicited msg print macro
99#define PRINTBUF_SIZE 8096
100
101// Enable verbose logging
102#define VDBG 0
103
104// Enable RILC log
105#define RILC_LOG 0
106
107#if RILC_LOG
108    #define startRequest           sprintf(printBuf, "(")
109    #define closeRequest           sprintf(printBuf, "%s)", printBuf)
110    #define printRequest(token, req)           \
111            RLOGD("[%04d]> %s %s", token, requestToString(req), printBuf)
112
113    #define startResponse           sprintf(printBuf, "%s {", printBuf)
114    #define closeResponse           sprintf(printBuf, "%s}", printBuf)
115    #define printResponse           RLOGD("%s", printBuf)
116
117    #define clearPrintBuf           printBuf[0] = 0
118    #define removeLastChar          printBuf[strlen(printBuf)-1] = 0
119    #define appendPrintBuf(x...)    snprintf(printBuf, PRINTBUF_SIZE, x)
120#else
121    #define startRequest
122    #define closeRequest
123    #define printRequest(token, req)
124    #define startResponse
125    #define closeResponse
126    #define printResponse
127    #define clearPrintBuf
128    #define removeLastChar
129    #define appendPrintBuf(x...)
130#endif
131
132enum WakeType {DONT_WAKE, WAKE_PARTIAL};
133
134typedef struct {
135    int requestNumber;
136    void (*dispatchFunction) (Parcel &p, struct RequestInfo *pRI);
137    int(*responseFunction) (Parcel &p, void *response, size_t responselen);
138} CommandInfo;
139
140typedef struct {
141    int requestNumber;
142    int (*responseFunction) (Parcel &p, void *response, size_t responselen);
143    WakeType wakeType;
144} UnsolResponseInfo;
145
146typedef struct RequestInfo {
147    int32_t token;      //this is not RIL_Token
148    CommandInfo *pCI;
149    struct RequestInfo *p_next;
150    char cancelled;
151    char local;         // responses to local commands do not go back to command process
152    RIL_SOCKET_ID socket_id;
153    int wasAckSent;    // Indicates whether an ack was sent earlier
154} RequestInfo;
155
156typedef struct UserCallbackInfo {
157    RIL_TimedCallback p_callback;
158    void *userParam;
159    struct ril_event event;
160    struct UserCallbackInfo *p_next;
161} UserCallbackInfo;
162
163extern "C" const char * requestToString(int request);
164extern "C" const char * failCauseToString(RIL_Errno);
165extern "C" const char * callStateToString(RIL_CallState);
166extern "C" const char * radioStateToString(RIL_RadioState);
167extern "C" const char * rilSocketIdToString(RIL_SOCKET_ID socket_id);
168
169extern "C"
170char rild[MAX_SOCKET_NAME_LENGTH] = SOCKET_NAME_RIL;
171/*******************************************************************/
172
173RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL};
174static int s_registerCalled = 0;
175
176static pthread_t s_tid_dispatch;
177static pthread_t s_tid_reader;
178static int s_started = 0;
179
180static int s_fdDebug = -1;
181static int s_fdDebug_socket2 = -1;
182
183static int s_fdWakeupRead;
184static int s_fdWakeupWrite;
185
186int s_wakelock_count = 0;
187
188static struct ril_event s_commands_event;
189static struct ril_event s_wakeupfd_event;
190static struct ril_event s_listen_event;
191static SocketListenParam s_ril_param_socket;
192
193static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER;
194static pthread_mutex_t s_writeMutex = PTHREAD_MUTEX_INITIALIZER;
195static pthread_mutex_t s_wakeLockCountMutex = PTHREAD_MUTEX_INITIALIZER;
196static RequestInfo *s_pendingRequests = NULL;
197
198#if (SIM_COUNT >= 2)
199static struct ril_event s_commands_event_socket2;
200static struct ril_event s_listen_event_socket2;
201static SocketListenParam s_ril_param_socket2;
202
203static pthread_mutex_t s_pendingRequestsMutex_socket2  = PTHREAD_MUTEX_INITIALIZER;
204static pthread_mutex_t s_writeMutex_socket2            = PTHREAD_MUTEX_INITIALIZER;
205static RequestInfo *s_pendingRequests_socket2          = NULL;
206#endif
207
208#if (SIM_COUNT >= 3)
209static struct ril_event s_commands_event_socket3;
210static struct ril_event s_listen_event_socket3;
211static SocketListenParam s_ril_param_socket3;
212
213static pthread_mutex_t s_pendingRequestsMutex_socket3  = PTHREAD_MUTEX_INITIALIZER;
214static pthread_mutex_t s_writeMutex_socket3            = PTHREAD_MUTEX_INITIALIZER;
215static RequestInfo *s_pendingRequests_socket3          = NULL;
216#endif
217
218#if (SIM_COUNT >= 4)
219static struct ril_event s_commands_event_socket4;
220static struct ril_event s_listen_event_socket4;
221static SocketListenParam s_ril_param_socket4;
222
223static pthread_mutex_t s_pendingRequestsMutex_socket4  = PTHREAD_MUTEX_INITIALIZER;
224static pthread_mutex_t s_writeMutex_socket4            = PTHREAD_MUTEX_INITIALIZER;
225static RequestInfo *s_pendingRequests_socket4          = NULL;
226#endif
227
228static struct ril_event s_wake_timeout_event;
229static struct ril_event s_debug_event;
230
231
232static const struct timeval TIMEVAL_WAKE_TIMEOUT = {ANDROID_WAKE_LOCK_SECS,ANDROID_WAKE_LOCK_USECS};
233
234
235static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
236static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER;
237
238static pthread_mutex_t s_dispatchMutex = PTHREAD_MUTEX_INITIALIZER;
239static pthread_cond_t s_dispatchCond = PTHREAD_COND_INITIALIZER;
240
241static RequestInfo *s_toDispatchHead = NULL;
242static RequestInfo *s_toDispatchTail = NULL;
243
244static UserCallbackInfo *s_last_wake_timeout_info = NULL;
245
246static void *s_lastNITZTimeData = NULL;
247static size_t s_lastNITZTimeDataSize;
248
249#if RILC_LOG
250    static char printBuf[PRINTBUF_SIZE];
251#endif
252
253/*******************************************************************/
254static int sendResponse (Parcel &p, RIL_SOCKET_ID socket_id);
255
256static void dispatchVoid (Parcel& p, RequestInfo *pRI);
257static void dispatchString (Parcel& p, RequestInfo *pRI);
258static void dispatchStrings (Parcel& p, RequestInfo *pRI);
259static void dispatchInts (Parcel& p, RequestInfo *pRI);
260static void dispatchDial (Parcel& p, RequestInfo *pRI);
261static void dispatchSIM_IO (Parcel& p, RequestInfo *pRI);
262static void dispatchSIM_APDU (Parcel& p, RequestInfo *pRI);
263static void dispatchCallForward(Parcel& p, RequestInfo *pRI);
264static void dispatchRaw(Parcel& p, RequestInfo *pRI);
265static void dispatchSmsWrite (Parcel &p, RequestInfo *pRI);
266static void dispatchDataCall (Parcel& p, RequestInfo *pRI);
267static void dispatchVoiceRadioTech (Parcel& p, RequestInfo *pRI);
268static void dispatchSetInitialAttachApn (Parcel& p, RequestInfo *pRI);
269static void dispatchCdmaSubscriptionSource (Parcel& p, RequestInfo *pRI);
270
271static void dispatchCdmaSms(Parcel &p, RequestInfo *pRI);
272static void dispatchImsSms(Parcel &p, RequestInfo *pRI);
273static void dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef);
274static void dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef);
275static void dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI);
276static void dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI);
277static void dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI);
278static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI);
279static void dispatchNVReadItem(Parcel &p, RequestInfo *pRI);
280static void dispatchNVWriteItem(Parcel &p, RequestInfo *pRI);
281static void dispatchUiccSubscripton(Parcel &p, RequestInfo *pRI);
282static void dispatchSimAuthentication(Parcel &p, RequestInfo *pRI);
283static void dispatchDataProfile(Parcel &p, RequestInfo *pRI);
284static void dispatchRadioCapability(Parcel &p, RequestInfo *pRI);
285static void dispatchCarrierRestrictions(Parcel &p, RequestInfo *pRI);
286static int responseInts(Parcel &p, void *response, size_t responselen);
287static int responseFailCause(Parcel &p, void *response, size_t responselen);
288static int responseStrings(Parcel &p, void *response, size_t responselen);
289static int responseString(Parcel &p, void *response, size_t responselen);
290static int responseVoid(Parcel &p, void *response, size_t responselen);
291static int responseCallList(Parcel &p, void *response, size_t responselen);
292static int responseSMS(Parcel &p, void *response, size_t responselen);
293static int responseSIM_IO(Parcel &p, void *response, size_t responselen);
294static int responseCallForwards(Parcel &p, void *response, size_t responselen);
295static int responseDataCallList(Parcel &p, void *response, size_t responselen);
296static int responseSetupDataCall(Parcel &p, void *response, size_t responselen);
297static int responseRaw(Parcel &p, void *response, size_t responselen);
298static int responseSsn(Parcel &p, void *response, size_t responselen);
299static int responseSimStatus(Parcel &p, void *response, size_t responselen);
300static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen);
301static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen);
302static int responseCdmaSms(Parcel &p, void *response, size_t responselen);
303static int responseCellList(Parcel &p, void *response, size_t responselen);
304static int responseCdmaInformationRecords(Parcel &p,void *response, size_t responselen);
305static int responseRilSignalStrength(Parcel &p,void *response, size_t responselen);
306static int responseCallRing(Parcel &p, void *response, size_t responselen);
307static int responseCdmaSignalInfoRecord(Parcel &p,void *response, size_t responselen);
308static int responseCdmaCallWaiting(Parcel &p,void *response, size_t responselen);
309static int responseSimRefresh(Parcel &p, void *response, size_t responselen);
310static int responseCellInfoList(Parcel &p, void *response, size_t responselen);
311static int responseHardwareConfig(Parcel &p, void *response, size_t responselen);
312static int responseDcRtInfo(Parcel &p, void *response, size_t responselen);
313static int responseRadioCapability(Parcel &p, void *response, size_t responselen);
314static int responseSSData(Parcel &p, void *response, size_t responselen);
315static int responseLceStatus(Parcel &p, void *response, size_t responselen);
316static int responseLceData(Parcel &p, void *response, size_t responselen);
317static int responseActivityData(Parcel &p, void *response, size_t responselen);
318static int responseCarrierRestrictions(Parcel &p, void *response, size_t responselen);
319static int responsePcoData(Parcel &p, void *response, size_t responselen);
320
321static int decodeVoiceRadioTechnology (RIL_RadioState radioState);
322static int decodeCdmaSubscriptionSource (RIL_RadioState radioState);
323static RIL_RadioState processRadioState(RIL_RadioState newRadioState);
324static void grabPartialWakeLock();
325static void releaseWakeLock();
326static void wakeTimeoutCallback(void *);
327
328static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType);
329
330static bool isDebuggable();
331
332#ifdef RIL_SHLIB
333#if defined(ANDROID_MULTI_SIM)
334extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
335                                size_t datalen, RIL_SOCKET_ID socket_id);
336#else
337extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
338                                size_t datalen);
339#endif
340#endif
341
342#if defined(ANDROID_MULTI_SIM)
343#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c), (d))
344#define CALL_ONREQUEST(a, b, c, d, e) s_callbacks.onRequest((a), (b), (c), (d), (e))
345#define CALL_ONSTATEREQUEST(a) s_callbacks.onStateRequest(a)
346#else
347#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c))
348#define CALL_ONREQUEST(a, b, c, d, e) s_callbacks.onRequest((a), (b), (c), (d))
349#define CALL_ONSTATEREQUEST(a) s_callbacks.onStateRequest()
350#endif
351
352static UserCallbackInfo * internalRequestTimedCallback
353    (RIL_TimedCallback callback, void *param,
354        const struct timeval *relativeTime);
355
356/** Index == requestNumber */
357static CommandInfo s_commands[] = {
358#include "ril_commands.h"
359};
360
361static UnsolResponseInfo s_unsolResponses[] = {
362#include "ril_unsol_commands.h"
363};
364
365/* For older RILs that do not support new commands RIL_REQUEST_VOICE_RADIO_TECH and
366   RIL_UNSOL_VOICE_RADIO_TECH_CHANGED messages, decode the voice radio tech from
367   radio state message and store it. Every time there is a change in Radio State
368   check to see if voice radio tech changes and notify telephony
369 */
370int voiceRadioTech = -1;
371
372/* For older RILs that do not support new commands RIL_REQUEST_GET_CDMA_SUBSCRIPTION_SOURCE
373   and RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED messages, decode the subscription
374   source from radio state and store it. Every time there is a change in Radio State
375   check to see if subscription source changed and notify telephony
376 */
377int cdmaSubscriptionSource = -1;
378
379/* For older RILs that do not send RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, decode the
380   SIM/RUIM state from radio state and store it. Every time there is a change in Radio State,
381   check to see if SIM/RUIM status changed and notify telephony
382 */
383int simRuimStatus = -1;
384
385static char * RIL_getRilSocketName() {
386    return rild;
387}
388
389extern "C"
390void RIL_setRilSocketName(const char * s) {
391    strncpy(rild, s, MAX_SOCKET_NAME_LENGTH);
392}
393
394static char *
395strdupReadString(Parcel &p) {
396    size_t stringlen;
397    const char16_t *s16;
398
399    s16 = p.readString16Inplace(&stringlen);
400
401    return strndup16to8(s16, stringlen);
402}
403
404static status_t
405readStringFromParcelInplace(Parcel &p, char *str, size_t maxLen) {
406    size_t s16Len;
407    const char16_t *s16;
408
409    s16 = p.readString16Inplace(&s16Len);
410    if (s16 == NULL) {
411        return NO_MEMORY;
412    }
413    size_t strLen = strnlen16to8(s16, s16Len);
414    if ((strLen + 1) > maxLen) {
415        return NO_MEMORY;
416    }
417    if (strncpy16to8(str, s16, strLen) == NULL) {
418        return NO_MEMORY;
419    } else {
420        return NO_ERROR;
421    }
422}
423
424static void writeStringToParcel(Parcel &p, const char *s) {
425    char16_t *s16;
426    size_t s16_len;
427    s16 = strdup8to16(s, &s16_len);
428    p.writeString16(s16, s16_len);
429    free(s16);
430}
431
432
433static void
434memsetString (char *s) {
435    if (s != NULL) {
436        memset (s, 0, strlen(s));
437    }
438}
439
440void   nullParcelReleaseFunction (const uint8_t* data, size_t dataSize,
441                                    const size_t* objects, size_t objectsSize,
442                                        void* cookie) {
443    // do nothing -- the data reference lives longer than the Parcel object
444}
445
446/**
447 * To be called from dispatch thread
448 * Issue a single local request, ensuring that the response
449 * is not sent back up to the command process
450 */
451static void
452issueLocalRequest(int request, void *data, int len, RIL_SOCKET_ID socket_id) {
453    RequestInfo *pRI;
454    int ret;
455    /* Hook for current context */
456    /* pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
457    pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
458    /* pendingRequestsHook refer to &s_pendingRequests */
459    RequestInfo**    pendingRequestsHook = &s_pendingRequests;
460
461#if (SIM_COUNT == 2)
462    if (socket_id == RIL_SOCKET_2) {
463        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
464        pendingRequestsHook = &s_pendingRequests_socket2;
465    }
466#endif
467
468    pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
469    if (pRI == NULL) {
470        RLOGE("Memory allocation failed for request %s", requestToString(request));
471        return;
472    }
473
474    pRI->local = 1;
475    pRI->token = 0xffffffff;        // token is not used in this context
476    pRI->pCI = &(s_commands[request]);
477    pRI->socket_id = socket_id;
478
479    ret = pthread_mutex_lock(pendingRequestsMutexHook);
480    assert (ret == 0);
481
482    pRI->p_next = *pendingRequestsHook;
483    *pendingRequestsHook = pRI;
484
485    ret = pthread_mutex_unlock(pendingRequestsMutexHook);
486    assert (ret == 0);
487
488    RLOGD("C[locl]> %s", requestToString(request));
489
490    CALL_ONREQUEST(request, data, len, pRI, pRI->socket_id);
491}
492
493
494
495static int
496processCommandBuffer(void *buffer, size_t buflen, RIL_SOCKET_ID socket_id) {
497    Parcel p;
498    status_t status;
499    int32_t request;
500    int32_t token;
501    RequestInfo *pRI;
502    int ret;
503    /* Hook for current context */
504    /* pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
505    pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
506    /* pendingRequestsHook refer to &s_pendingRequests */
507    RequestInfo**    pendingRequestsHook = &s_pendingRequests;
508
509    p.setData((uint8_t *) buffer, buflen);
510
511    // status checked at end
512    status = p.readInt32(&request);
513    status = p.readInt32 (&token);
514
515#if (SIM_COUNT >= 2)
516    if (socket_id == RIL_SOCKET_2) {
517        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
518        pendingRequestsHook = &s_pendingRequests_socket2;
519    }
520#if (SIM_COUNT >= 3)
521    else if (socket_id == RIL_SOCKET_3) {
522        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
523        pendingRequestsHook = &s_pendingRequests_socket3;
524    }
525#endif
526#if (SIM_COUNT >= 4)
527    else if (socket_id == RIL_SOCKET_4) {
528        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
529        pendingRequestsHook = &s_pendingRequests_socket4;
530    }
531#endif
532#endif
533
534    if (status != NO_ERROR) {
535        RLOGE("invalid request block");
536        return 0;
537    }
538
539    // Received an Ack for the previous result sent to RIL.java,
540    // so release wakelock and exit
541    if (request == RIL_RESPONSE_ACKNOWLEDGEMENT) {
542        releaseWakeLock();
543        return 0;
544    }
545
546    if (request < 1 || request >= (int32_t)NUM_ELEMS(s_commands)) {
547        Parcel pErr;
548        RLOGE("unsupported request code %d token %d", request, token);
549        // FIXME this should perhaps return a response
550        pErr.writeInt32 (RESPONSE_SOLICITED);
551        pErr.writeInt32 (token);
552        pErr.writeInt32 (RIL_E_GENERIC_FAILURE);
553
554        sendResponse(pErr, socket_id);
555        return 0;
556    }
557
558    pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
559    if (pRI == NULL) {
560        RLOGE("Memory allocation failed for request %s", requestToString(request));
561        return 0;
562    }
563
564    pRI->token = token;
565    pRI->pCI = &(s_commands[request]);
566    pRI->socket_id = socket_id;
567
568    ret = pthread_mutex_lock(pendingRequestsMutexHook);
569    assert (ret == 0);
570
571    pRI->p_next = *pendingRequestsHook;
572    *pendingRequestsHook = pRI;
573
574    ret = pthread_mutex_unlock(pendingRequestsMutexHook);
575    assert (ret == 0);
576
577/*    sLastDispatchedToken = token; */
578
579    pRI->pCI->dispatchFunction(p, pRI);
580
581    return 0;
582}
583
584static void
585invalidCommandBlock (RequestInfo *pRI) {
586    RLOGE("invalid command block for token %d request %s",
587                pRI->token, requestToString(pRI->pCI->requestNumber));
588}
589
590/** Callee expects NULL */
591static void
592dispatchVoid (Parcel& p, RequestInfo *pRI) {
593    clearPrintBuf;
594    printRequest(pRI->token, pRI->pCI->requestNumber);
595    CALL_ONREQUEST(pRI->pCI->requestNumber, NULL, 0, pRI, pRI->socket_id);
596}
597
598/** Callee expects const char * */
599static void
600dispatchString (Parcel& p, RequestInfo *pRI) {
601    status_t status;
602    size_t datalen;
603    size_t stringlen;
604    char *string8 = NULL;
605
606    string8 = strdupReadString(p);
607
608    startRequest;
609    appendPrintBuf("%s%s", printBuf, string8);
610    closeRequest;
611    printRequest(pRI->token, pRI->pCI->requestNumber);
612
613    CALL_ONREQUEST(pRI->pCI->requestNumber, string8,
614                       sizeof(char *), pRI, pRI->socket_id);
615
616#ifdef MEMSET_FREED
617    memsetString(string8);
618#endif
619
620    free(string8);
621    return;
622invalid:
623    invalidCommandBlock(pRI);
624    return;
625}
626
627/** Callee expects const char ** */
628static void
629dispatchStrings (Parcel &p, RequestInfo *pRI) {
630    int32_t countStrings;
631    status_t status;
632    size_t datalen;
633    char **pStrings;
634
635    status = p.readInt32 (&countStrings);
636
637    if (status != NO_ERROR) {
638        goto invalid;
639    }
640
641    startRequest;
642    if (countStrings == 0) {
643        // just some non-null pointer
644        pStrings = (char **)calloc(1, sizeof(char *));
645        if (pStrings == NULL) {
646            RLOGE("Memory allocation failed for request %s",
647                    requestToString(pRI->pCI->requestNumber));
648            closeRequest;
649            return;
650        }
651
652        datalen = 0;
653    } else if (countStrings < 0) {
654        pStrings = NULL;
655        datalen = 0;
656    } else {
657        datalen = sizeof(char *) * countStrings;
658
659        pStrings = (char **)calloc(countStrings, sizeof(char *));
660        if (pStrings == NULL) {
661            RLOGE("Memory allocation failed for request %s",
662                    requestToString(pRI->pCI->requestNumber));
663            closeRequest;
664            return;
665        }
666
667        for (int i = 0 ; i < countStrings ; i++) {
668            pStrings[i] = strdupReadString(p);
669            appendPrintBuf("%s%s,", printBuf, pStrings[i]);
670        }
671    }
672    removeLastChar;
673    closeRequest;
674    printRequest(pRI->token, pRI->pCI->requestNumber);
675
676    CALL_ONREQUEST(pRI->pCI->requestNumber, pStrings, datalen, pRI, pRI->socket_id);
677
678    if (pStrings != NULL) {
679        for (int i = 0 ; i < countStrings ; i++) {
680#ifdef MEMSET_FREED
681            memsetString (pStrings[i]);
682#endif
683            free(pStrings[i]);
684        }
685
686#ifdef MEMSET_FREED
687        memset(pStrings, 0, datalen);
688#endif
689        free(pStrings);
690    }
691
692    return;
693invalid:
694    invalidCommandBlock(pRI);
695    return;
696}
697
698/** Callee expects const int * */
699static void
700dispatchInts (Parcel &p, RequestInfo *pRI) {
701    int32_t count;
702    status_t status;
703    size_t datalen;
704    int *pInts;
705
706    status = p.readInt32 (&count);
707
708    if (status != NO_ERROR || count <= 0) {
709        goto invalid;
710    }
711
712    datalen = sizeof(int) * count;
713    pInts = (int *)calloc(count, sizeof(int));
714    if (pInts == NULL) {
715        RLOGE("Memory allocation failed for request %s", requestToString(pRI->pCI->requestNumber));
716        return;
717    }
718
719    startRequest;
720    for (int i = 0 ; i < count ; i++) {
721        int32_t t;
722
723        status = p.readInt32(&t);
724        pInts[i] = (int)t;
725        appendPrintBuf("%s%d,", printBuf, t);
726
727        if (status != NO_ERROR) {
728            free(pInts);
729            goto invalid;
730        }
731   }
732   removeLastChar;
733   closeRequest;
734   printRequest(pRI->token, pRI->pCI->requestNumber);
735
736   CALL_ONREQUEST(pRI->pCI->requestNumber, const_cast<int *>(pInts),
737                       datalen, pRI, pRI->socket_id);
738
739#ifdef MEMSET_FREED
740    memset(pInts, 0, datalen);
741#endif
742    free(pInts);
743    return;
744invalid:
745    invalidCommandBlock(pRI);
746    return;
747}
748
749
750/**
751 * Callee expects const RIL_SMS_WriteArgs *
752 * Payload is:
753 *   int32_t status
754 *   String pdu
755 */
756static void
757dispatchSmsWrite (Parcel &p, RequestInfo *pRI) {
758    RIL_SMS_WriteArgs args;
759    int32_t t;
760    status_t status;
761
762    RLOGD("dispatchSmsWrite");
763    memset (&args, 0, sizeof(args));
764
765    status = p.readInt32(&t);
766    args.status = (int)t;
767
768    args.pdu = strdupReadString(p);
769
770    if (status != NO_ERROR || args.pdu == NULL) {
771        goto invalid;
772    }
773
774    args.smsc = strdupReadString(p);
775
776    startRequest;
777    appendPrintBuf("%s%d,%s,smsc=%s", printBuf, args.status,
778        (char*)args.pdu,  (char*)args.smsc);
779    closeRequest;
780    printRequest(pRI->token, pRI->pCI->requestNumber);
781
782    CALL_ONREQUEST(pRI->pCI->requestNumber, &args, sizeof(args), pRI, pRI->socket_id);
783
784#ifdef MEMSET_FREED
785    memsetString (args.pdu);
786#endif
787
788    free (args.pdu);
789
790#ifdef MEMSET_FREED
791    memset(&args, 0, sizeof(args));
792#endif
793
794    return;
795invalid:
796    invalidCommandBlock(pRI);
797    return;
798}
799
800/**
801 * Callee expects const RIL_Dial *
802 * Payload is:
803 *   String address
804 *   int32_t clir
805 */
806static void
807dispatchDial (Parcel &p, RequestInfo *pRI) {
808    RIL_Dial dial;
809    RIL_UUS_Info uusInfo;
810    int32_t sizeOfDial;
811    int32_t t;
812    int32_t uusPresent;
813    status_t status;
814
815    RLOGD("dispatchDial");
816    memset (&dial, 0, sizeof(dial));
817
818    dial.address = strdupReadString(p);
819
820    status = p.readInt32(&t);
821    dial.clir = (int)t;
822
823    if (status != NO_ERROR || dial.address == NULL) {
824        goto invalid;
825    }
826
827    if (s_callbacks.version < 3) { // Remove when partners upgrade to version 3
828        uusPresent = 0;
829        sizeOfDial = sizeof(dial) - sizeof(RIL_UUS_Info *);
830    } else {
831        status = p.readInt32(&uusPresent);
832
833        if (status != NO_ERROR) {
834            goto invalid;
835        }
836
837        if (uusPresent == 0) {
838            dial.uusInfo = NULL;
839        } else {
840            int32_t len;
841
842            memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
843
844            status = p.readInt32(&t);
845            uusInfo.uusType = (RIL_UUS_Type) t;
846
847            status = p.readInt32(&t);
848            uusInfo.uusDcs = (RIL_UUS_DCS) t;
849
850            status = p.readInt32(&len);
851            if (status != NO_ERROR) {
852                goto invalid;
853            }
854
855            // The java code writes -1 for null arrays
856            if (((int) len) == -1) {
857                uusInfo.uusData = NULL;
858                len = 0;
859            } else {
860                uusInfo.uusData = (char*) p.readInplace(len);
861            }
862
863            uusInfo.uusLength = len;
864            dial.uusInfo = &uusInfo;
865        }
866        sizeOfDial = sizeof(dial);
867    }
868
869    startRequest;
870    appendPrintBuf("%snum=%s,clir=%d", printBuf, dial.address, dial.clir);
871    if (uusPresent) {
872        appendPrintBuf("%s,uusType=%d,uusDcs=%d,uusLen=%d", printBuf,
873                dial.uusInfo->uusType, dial.uusInfo->uusDcs,
874                dial.uusInfo->uusLength);
875    }
876    closeRequest;
877    printRequest(pRI->token, pRI->pCI->requestNumber);
878
879    CALL_ONREQUEST(pRI->pCI->requestNumber, &dial, sizeOfDial, pRI, pRI->socket_id);
880
881#ifdef MEMSET_FREED
882    memsetString (dial.address);
883#endif
884
885    free (dial.address);
886
887#ifdef MEMSET_FREED
888    memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
889    memset(&dial, 0, sizeof(dial));
890#endif
891
892    return;
893invalid:
894    invalidCommandBlock(pRI);
895    return;
896}
897
898/**
899 * Callee expects const RIL_SIM_IO *
900 * Payload is:
901 *   int32_t command
902 *   int32_t fileid
903 *   String path
904 *   int32_t p1, p2, p3
905 *   String data
906 *   String pin2
907 *   String aidPtr
908 */
909static void
910dispatchSIM_IO (Parcel &p, RequestInfo *pRI) {
911    union RIL_SIM_IO {
912        RIL_SIM_IO_v6 v6;
913        RIL_SIM_IO_v5 v5;
914    } simIO;
915
916    int32_t t;
917    int size;
918    status_t status;
919
920#if VDBG
921    RLOGD("dispatchSIM_IO");
922#endif
923    memset (&simIO, 0, sizeof(simIO));
924
925    // note we only check status at the end
926
927    status = p.readInt32(&t);
928    simIO.v6.command = (int)t;
929
930    status = p.readInt32(&t);
931    simIO.v6.fileid = (int)t;
932
933    simIO.v6.path = strdupReadString(p);
934
935    status = p.readInt32(&t);
936    simIO.v6.p1 = (int)t;
937
938    status = p.readInt32(&t);
939    simIO.v6.p2 = (int)t;
940
941    status = p.readInt32(&t);
942    simIO.v6.p3 = (int)t;
943
944    simIO.v6.data = strdupReadString(p);
945    simIO.v6.pin2 = strdupReadString(p);
946    simIO.v6.aidPtr = strdupReadString(p);
947
948    startRequest;
949    appendPrintBuf("%scmd=0x%X,efid=0x%X,path=%s,%d,%d,%d,%s,pin2=%s,aid=%s", printBuf,
950        simIO.v6.command, simIO.v6.fileid, (char*)simIO.v6.path,
951        simIO.v6.p1, simIO.v6.p2, simIO.v6.p3,
952        (char*)simIO.v6.data,  (char*)simIO.v6.pin2, simIO.v6.aidPtr);
953    closeRequest;
954    printRequest(pRI->token, pRI->pCI->requestNumber);
955
956    if (status != NO_ERROR) {
957        goto invalid;
958    }
959
960    size = (s_callbacks.version < 6) ? sizeof(simIO.v5) : sizeof(simIO.v6);
961    CALL_ONREQUEST(pRI->pCI->requestNumber, &simIO, size, pRI, pRI->socket_id);
962
963#ifdef MEMSET_FREED
964    memsetString (simIO.v6.path);
965    memsetString (simIO.v6.data);
966    memsetString (simIO.v6.pin2);
967    memsetString (simIO.v6.aidPtr);
968#endif
969
970    free (simIO.v6.path);
971    free (simIO.v6.data);
972    free (simIO.v6.pin2);
973    free (simIO.v6.aidPtr);
974
975#ifdef MEMSET_FREED
976    memset(&simIO, 0, sizeof(simIO));
977#endif
978
979    return;
980invalid:
981    invalidCommandBlock(pRI);
982    return;
983}
984
985/**
986 * Callee expects const RIL_SIM_APDU *
987 * Payload is:
988 *   int32_t sessionid
989 *   int32_t cla
990 *   int32_t instruction
991 *   int32_t p1, p2, p3
992 *   String data
993 */
994static void
995dispatchSIM_APDU (Parcel &p, RequestInfo *pRI) {
996    int32_t t;
997    status_t status;
998    RIL_SIM_APDU apdu;
999
1000#if VDBG
1001    RLOGD("dispatchSIM_APDU");
1002#endif
1003    memset (&apdu, 0, sizeof(RIL_SIM_APDU));
1004
1005    // Note we only check status at the end. Any single failure leads to
1006    // subsequent reads filing.
1007    status = p.readInt32(&t);
1008    apdu.sessionid = (int)t;
1009
1010    status = p.readInt32(&t);
1011    apdu.cla = (int)t;
1012
1013    status = p.readInt32(&t);
1014    apdu.instruction = (int)t;
1015
1016    status = p.readInt32(&t);
1017    apdu.p1 = (int)t;
1018
1019    status = p.readInt32(&t);
1020    apdu.p2 = (int)t;
1021
1022    status = p.readInt32(&t);
1023    apdu.p3 = (int)t;
1024
1025    apdu.data = strdupReadString(p);
1026
1027    startRequest;
1028    appendPrintBuf("%ssessionid=%d,cla=%d,ins=%d,p1=%d,p2=%d,p3=%d,data=%s",
1029        printBuf, apdu.sessionid, apdu.cla, apdu.instruction, apdu.p1, apdu.p2,
1030        apdu.p3, (char*)apdu.data);
1031    closeRequest;
1032    printRequest(pRI->token, pRI->pCI->requestNumber);
1033
1034    if (status != NO_ERROR) {
1035        goto invalid;
1036    }
1037
1038    CALL_ONREQUEST(pRI->pCI->requestNumber, &apdu, sizeof(RIL_SIM_APDU), pRI, pRI->socket_id);
1039
1040#ifdef MEMSET_FREED
1041    memsetString(apdu.data);
1042#endif
1043    free(apdu.data);
1044
1045#ifdef MEMSET_FREED
1046    memset(&apdu, 0, sizeof(RIL_SIM_APDU));
1047#endif
1048
1049    return;
1050invalid:
1051    invalidCommandBlock(pRI);
1052    return;
1053}
1054
1055
1056/**
1057 * Callee expects const RIL_CallForwardInfo *
1058 * Payload is:
1059 *  int32_t status/action
1060 *  int32_t reason
1061 *  int32_t serviceCode
1062 *  int32_t toa
1063 *  String number  (0 length -> null)
1064 *  int32_t timeSeconds
1065 */
1066static void
1067dispatchCallForward(Parcel &p, RequestInfo *pRI) {
1068    RIL_CallForwardInfo cff;
1069    int32_t t;
1070    status_t status;
1071
1072    RLOGD("dispatchCallForward");
1073    memset (&cff, 0, sizeof(cff));
1074
1075    // note we only check status at the end
1076
1077    status = p.readInt32(&t);
1078    cff.status = (int)t;
1079
1080    status = p.readInt32(&t);
1081    cff.reason = (int)t;
1082
1083    status = p.readInt32(&t);
1084    cff.serviceClass = (int)t;
1085
1086    status = p.readInt32(&t);
1087    cff.toa = (int)t;
1088
1089    cff.number = strdupReadString(p);
1090
1091    status = p.readInt32(&t);
1092    cff.timeSeconds = (int)t;
1093
1094    if (status != NO_ERROR) {
1095        goto invalid;
1096    }
1097
1098    // special case: number 0-length fields is null
1099
1100    if (cff.number != NULL && strlen (cff.number) == 0) {
1101        cff.number = NULL;
1102    }
1103
1104    startRequest;
1105    appendPrintBuf("%sstat=%d,reason=%d,serv=%d,toa=%d,%s,tout=%d", printBuf,
1106        cff.status, cff.reason, cff.serviceClass, cff.toa,
1107        (char*)cff.number, cff.timeSeconds);
1108    closeRequest;
1109    printRequest(pRI->token, pRI->pCI->requestNumber);
1110
1111    CALL_ONREQUEST(pRI->pCI->requestNumber, &cff, sizeof(cff), pRI, pRI->socket_id);
1112
1113#ifdef MEMSET_FREED
1114    memsetString(cff.number);
1115#endif
1116
1117    free (cff.number);
1118
1119#ifdef MEMSET_FREED
1120    memset(&cff, 0, sizeof(cff));
1121#endif
1122
1123    return;
1124invalid:
1125    invalidCommandBlock(pRI);
1126    return;
1127}
1128
1129
1130static void
1131dispatchRaw(Parcel &p, RequestInfo *pRI) {
1132    int32_t len;
1133    status_t status;
1134    const void *data;
1135
1136    status = p.readInt32(&len);
1137
1138    if (status != NO_ERROR) {
1139        goto invalid;
1140    }
1141
1142    // The java code writes -1 for null arrays
1143    if (((int)len) == -1) {
1144        data = NULL;
1145        len = 0;
1146    }
1147
1148    data = p.readInplace(len);
1149
1150    startRequest;
1151    appendPrintBuf("%sraw_size=%d", printBuf, len);
1152    closeRequest;
1153    printRequest(pRI->token, pRI->pCI->requestNumber);
1154
1155    CALL_ONREQUEST(pRI->pCI->requestNumber, const_cast<void *>(data), len, pRI, pRI->socket_id);
1156
1157    return;
1158invalid:
1159    invalidCommandBlock(pRI);
1160    return;
1161}
1162
1163static status_t
1164constructCdmaSms(Parcel &p, RequestInfo *pRI, RIL_CDMA_SMS_Message& rcsm) {
1165    int32_t  t;
1166    uint8_t ut;
1167    status_t status;
1168    int32_t digitCount;
1169    int digitLimit;
1170
1171    memset(&rcsm, 0, sizeof(rcsm));
1172
1173    status = p.readInt32(&t);
1174    rcsm.uTeleserviceID = (int) t;
1175
1176    status = p.read(&ut,sizeof(ut));
1177    rcsm.bIsServicePresent = (uint8_t) ut;
1178
1179    status = p.readInt32(&t);
1180    rcsm.uServicecategory = (int) t;
1181
1182    status = p.readInt32(&t);
1183    rcsm.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
1184
1185    status = p.readInt32(&t);
1186    rcsm.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
1187
1188    status = p.readInt32(&t);
1189    rcsm.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
1190
1191    status = p.readInt32(&t);
1192    rcsm.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
1193
1194    status = p.read(&ut,sizeof(ut));
1195    rcsm.sAddress.number_of_digits= (uint8_t) ut;
1196
1197    digitLimit= MIN((rcsm.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
1198    for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1199        status = p.read(&ut,sizeof(ut));
1200        rcsm.sAddress.digits[digitCount] = (uint8_t) ut;
1201    }
1202
1203    status = p.readInt32(&t);
1204    rcsm.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
1205
1206    status = p.read(&ut,sizeof(ut));
1207    rcsm.sSubAddress.odd = (uint8_t) ut;
1208
1209    status = p.read(&ut,sizeof(ut));
1210    rcsm.sSubAddress.number_of_digits = (uint8_t) ut;
1211
1212    digitLimit= MIN((rcsm.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
1213    for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1214        status = p.read(&ut,sizeof(ut));
1215        rcsm.sSubAddress.digits[digitCount] = (uint8_t) ut;
1216    }
1217
1218    status = p.readInt32(&t);
1219    rcsm.uBearerDataLen = (int) t;
1220
1221    digitLimit= MIN((rcsm.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
1222    for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1223        status = p.read(&ut, sizeof(ut));
1224        rcsm.aBearerData[digitCount] = (uint8_t) ut;
1225    }
1226
1227    if (status != NO_ERROR) {
1228        return status;
1229    }
1230
1231    startRequest;
1232    appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
1233            sAddress.digit_mode=%d, sAddress.Number_mode=%d, sAddress.number_type=%d, ",
1234            printBuf, rcsm.uTeleserviceID,rcsm.bIsServicePresent,rcsm.uServicecategory,
1235            rcsm.sAddress.digit_mode, rcsm.sAddress.number_mode,rcsm.sAddress.number_type);
1236    closeRequest;
1237
1238    printRequest(pRI->token, pRI->pCI->requestNumber);
1239
1240    return status;
1241}
1242
1243static void
1244dispatchCdmaSms(Parcel &p, RequestInfo *pRI) {
1245    RIL_CDMA_SMS_Message rcsm;
1246
1247    RLOGD("dispatchCdmaSms");
1248    if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) {
1249        goto invalid;
1250    }
1251
1252    CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm),pRI, pRI->socket_id);
1253
1254#ifdef MEMSET_FREED
1255    memset(&rcsm, 0, sizeof(rcsm));
1256#endif
1257
1258    return;
1259
1260invalid:
1261    invalidCommandBlock(pRI);
1262    return;
1263}
1264
1265static void
1266dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) {
1267    RIL_IMS_SMS_Message rism;
1268    RIL_CDMA_SMS_Message rcsm;
1269
1270    RLOGD("dispatchImsCdmaSms: retry=%d, messageRef=%d", retry, messageRef);
1271
1272    if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) {
1273        goto invalid;
1274    }
1275    memset(&rism, 0, sizeof(rism));
1276    rism.tech = RADIO_TECH_3GPP2;
1277    rism.retry = retry;
1278    rism.messageRef = messageRef;
1279    rism.message.cdmaMessage = &rcsm;
1280
1281    CALL_ONREQUEST(pRI->pCI->requestNumber, &rism,
1282            sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t)
1283            +sizeof(rcsm),pRI, pRI->socket_id);
1284
1285#ifdef MEMSET_FREED
1286    memset(&rcsm, 0, sizeof(rcsm));
1287    memset(&rism, 0, sizeof(rism));
1288#endif
1289
1290    return;
1291
1292invalid:
1293    invalidCommandBlock(pRI);
1294    return;
1295}
1296
1297static void
1298dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) {
1299    RIL_IMS_SMS_Message rism;
1300    int32_t countStrings;
1301    status_t status;
1302    size_t datalen;
1303    char **pStrings;
1304    RLOGD("dispatchImsGsmSms: retry=%d, messageRef=%d", retry, messageRef);
1305
1306    status = p.readInt32 (&countStrings);
1307
1308    if (status != NO_ERROR) {
1309        goto invalid;
1310    }
1311
1312    memset(&rism, 0, sizeof(rism));
1313    rism.tech = RADIO_TECH_3GPP;
1314    rism.retry = retry;
1315    rism.messageRef = messageRef;
1316
1317    startRequest;
1318    appendPrintBuf("%stech=%d, retry=%d, messageRef=%d, ", printBuf,
1319                    (int)rism.tech, (int)rism.retry, rism.messageRef);
1320    if (countStrings == 0) {
1321        // just some non-null pointer
1322        pStrings = (char **)calloc(1, sizeof(char *));
1323        if (pStrings == NULL) {
1324            RLOGE("Memory allocation failed for request %s",
1325                    requestToString(pRI->pCI->requestNumber));
1326            closeRequest;
1327            return;
1328        }
1329
1330        datalen = 0;
1331    } else if (countStrings < 0) {
1332        pStrings = NULL;
1333        datalen = 0;
1334    } else {
1335        if ((size_t)countStrings > (INT_MAX/sizeof(char *))) {
1336            RLOGE("Invalid value of countStrings: \n");
1337            closeRequest;
1338            return;
1339        }
1340        datalen = sizeof(char *) * countStrings;
1341
1342        pStrings = (char **)calloc(countStrings, sizeof(char *));
1343        if (pStrings == NULL) {
1344            RLOGE("Memory allocation failed for request %s",
1345                    requestToString(pRI->pCI->requestNumber));
1346            closeRequest;
1347            return;
1348        }
1349
1350        for (int i = 0 ; i < countStrings ; i++) {
1351            pStrings[i] = strdupReadString(p);
1352            appendPrintBuf("%s%s,", printBuf, pStrings[i]);
1353        }
1354    }
1355    removeLastChar;
1356    closeRequest;
1357    printRequest(pRI->token, pRI->pCI->requestNumber);
1358
1359    rism.message.gsmMessage = pStrings;
1360    CALL_ONREQUEST(pRI->pCI->requestNumber, &rism,
1361            sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t)
1362            +datalen, pRI, pRI->socket_id);
1363
1364    if (pStrings != NULL) {
1365        for (int i = 0 ; i < countStrings ; i++) {
1366#ifdef MEMSET_FREED
1367            memsetString (pStrings[i]);
1368#endif
1369            free(pStrings[i]);
1370        }
1371
1372#ifdef MEMSET_FREED
1373        memset(pStrings, 0, datalen);
1374#endif
1375        free(pStrings);
1376    }
1377
1378#ifdef MEMSET_FREED
1379    memset(&rism, 0, sizeof(rism));
1380#endif
1381    return;
1382invalid:
1383    ALOGE("dispatchImsGsmSms invalid block");
1384    invalidCommandBlock(pRI);
1385    return;
1386}
1387
1388static void
1389dispatchImsSms(Parcel &p, RequestInfo *pRI) {
1390    int32_t  t;
1391    status_t status = p.readInt32(&t);
1392    RIL_RadioTechnologyFamily format;
1393    uint8_t retry;
1394    int32_t messageRef;
1395
1396    RLOGD("dispatchImsSms");
1397    if (status != NO_ERROR) {
1398        goto invalid;
1399    }
1400    format = (RIL_RadioTechnologyFamily) t;
1401
1402    // read retry field
1403    status = p.read(&retry,sizeof(retry));
1404    if (status != NO_ERROR) {
1405        goto invalid;
1406    }
1407    // read messageRef field
1408    status = p.read(&messageRef,sizeof(messageRef));
1409    if (status != NO_ERROR) {
1410        goto invalid;
1411    }
1412
1413    if (RADIO_TECH_3GPP == format) {
1414        dispatchImsGsmSms(p, pRI, retry, messageRef);
1415    } else if (RADIO_TECH_3GPP2 == format) {
1416        dispatchImsCdmaSms(p, pRI, retry, messageRef);
1417    } else {
1418        ALOGE("requestImsSendSMS invalid format value =%d", format);
1419    }
1420
1421    return;
1422
1423invalid:
1424    invalidCommandBlock(pRI);
1425    return;
1426}
1427
1428static void
1429dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI) {
1430    RIL_CDMA_SMS_Ack rcsa;
1431    int32_t  t;
1432    status_t status;
1433    int32_t digitCount;
1434
1435    RLOGD("dispatchCdmaSmsAck");
1436    memset(&rcsa, 0, sizeof(rcsa));
1437
1438    status = p.readInt32(&t);
1439    rcsa.uErrorClass = (RIL_CDMA_SMS_ErrorClass) t;
1440
1441    status = p.readInt32(&t);
1442    rcsa.uSMSCauseCode = (int) t;
1443
1444    if (status != NO_ERROR) {
1445        goto invalid;
1446    }
1447
1448    startRequest;
1449    appendPrintBuf("%suErrorClass=%d, uTLStatus=%d, ",
1450            printBuf, rcsa.uErrorClass, rcsa.uSMSCauseCode);
1451    closeRequest;
1452
1453    printRequest(pRI->token, pRI->pCI->requestNumber);
1454
1455    CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa),pRI, pRI->socket_id);
1456
1457#ifdef MEMSET_FREED
1458    memset(&rcsa, 0, sizeof(rcsa));
1459#endif
1460
1461    return;
1462
1463invalid:
1464    invalidCommandBlock(pRI);
1465    return;
1466}
1467
1468static void
1469dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI) {
1470    int32_t t;
1471    status_t status;
1472    int32_t num;
1473
1474    status = p.readInt32(&num);
1475    if (status != NO_ERROR) {
1476        goto invalid;
1477    }
1478
1479    {
1480        RIL_GSM_BroadcastSmsConfigInfo gsmBci[num];
1481        RIL_GSM_BroadcastSmsConfigInfo *gsmBciPtrs[num];
1482
1483        startRequest;
1484        for (int i = 0 ; i < num ; i++ ) {
1485            gsmBciPtrs[i] = &gsmBci[i];
1486
1487            status = p.readInt32(&t);
1488            gsmBci[i].fromServiceId = (int) t;
1489
1490            status = p.readInt32(&t);
1491            gsmBci[i].toServiceId = (int) t;
1492
1493            status = p.readInt32(&t);
1494            gsmBci[i].fromCodeScheme = (int) t;
1495
1496            status = p.readInt32(&t);
1497            gsmBci[i].toCodeScheme = (int) t;
1498
1499            status = p.readInt32(&t);
1500            gsmBci[i].selected = (uint8_t) t;
1501
1502            appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId =%d, \
1503                  fromCodeScheme=%d, toCodeScheme=%d, selected =%d]", printBuf, i,
1504                  gsmBci[i].fromServiceId, gsmBci[i].toServiceId,
1505                  gsmBci[i].fromCodeScheme, gsmBci[i].toCodeScheme,
1506                  gsmBci[i].selected);
1507        }
1508        closeRequest;
1509
1510        if (status != NO_ERROR) {
1511            goto invalid;
1512        }
1513
1514        CALL_ONREQUEST(pRI->pCI->requestNumber,
1515                              gsmBciPtrs,
1516                              num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *),
1517                              pRI, pRI->socket_id);
1518
1519#ifdef MEMSET_FREED
1520        memset(gsmBci, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo));
1521        memset(gsmBciPtrs, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *));
1522#endif
1523    }
1524
1525    return;
1526
1527invalid:
1528    invalidCommandBlock(pRI);
1529    return;
1530}
1531
1532static void
1533dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI) {
1534    int32_t t;
1535    status_t status;
1536    int32_t num;
1537
1538    status = p.readInt32(&num);
1539    if (status != NO_ERROR) {
1540        goto invalid;
1541    }
1542
1543    {
1544        RIL_CDMA_BroadcastSmsConfigInfo cdmaBci[num];
1545        RIL_CDMA_BroadcastSmsConfigInfo *cdmaBciPtrs[num];
1546
1547        startRequest;
1548        for (int i = 0 ; i < num ; i++ ) {
1549            cdmaBciPtrs[i] = &cdmaBci[i];
1550
1551            status = p.readInt32(&t);
1552            cdmaBci[i].service_category = (int) t;
1553
1554            status = p.readInt32(&t);
1555            cdmaBci[i].language = (int) t;
1556
1557            status = p.readInt32(&t);
1558            cdmaBci[i].selected = (uint8_t) t;
1559
1560            appendPrintBuf("%s [%d: service_category=%d, language =%d, \
1561                  entries.bSelected =%d]", printBuf, i, cdmaBci[i].service_category,
1562                  cdmaBci[i].language, cdmaBci[i].selected);
1563        }
1564        closeRequest;
1565
1566        if (status != NO_ERROR) {
1567            goto invalid;
1568        }
1569
1570        CALL_ONREQUEST(pRI->pCI->requestNumber,
1571                              cdmaBciPtrs,
1572                              num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *),
1573                              pRI, pRI->socket_id);
1574
1575#ifdef MEMSET_FREED
1576        memset(cdmaBci, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo));
1577        memset(cdmaBciPtrs, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *));
1578#endif
1579    }
1580
1581    return;
1582
1583invalid:
1584    invalidCommandBlock(pRI);
1585    return;
1586}
1587
1588static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI) {
1589    RIL_CDMA_SMS_WriteArgs rcsw;
1590    int32_t  t;
1591    uint32_t ut;
1592    uint8_t  uct;
1593    status_t status;
1594    int32_t  digitCount;
1595    int32_t  digitLimit;
1596
1597    memset(&rcsw, 0, sizeof(rcsw));
1598
1599    status = p.readInt32(&t);
1600    rcsw.status = t;
1601
1602    status = p.readInt32(&t);
1603    rcsw.message.uTeleserviceID = (int) t;
1604
1605    status = p.read(&uct,sizeof(uct));
1606    rcsw.message.bIsServicePresent = (uint8_t) uct;
1607
1608    status = p.readInt32(&t);
1609    rcsw.message.uServicecategory = (int) t;
1610
1611    status = p.readInt32(&t);
1612    rcsw.message.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
1613
1614    status = p.readInt32(&t);
1615    rcsw.message.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
1616
1617    status = p.readInt32(&t);
1618    rcsw.message.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
1619
1620    status = p.readInt32(&t);
1621    rcsw.message.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
1622
1623    status = p.read(&uct,sizeof(uct));
1624    rcsw.message.sAddress.number_of_digits = (uint8_t) uct;
1625
1626    digitLimit = MIN((rcsw.message.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
1627
1628    for(digitCount = 0 ; digitCount < digitLimit; digitCount ++) {
1629        status = p.read(&uct,sizeof(uct));
1630        rcsw.message.sAddress.digits[digitCount] = (uint8_t) uct;
1631    }
1632
1633    status = p.readInt32(&t);
1634    rcsw.message.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
1635
1636    status = p.read(&uct,sizeof(uct));
1637    rcsw.message.sSubAddress.odd = (uint8_t) uct;
1638
1639    status = p.read(&uct,sizeof(uct));
1640    rcsw.message.sSubAddress.number_of_digits = (uint8_t) uct;
1641
1642    digitLimit = MIN((rcsw.message.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
1643
1644    for(digitCount = 0 ; digitCount < digitLimit; digitCount ++) {
1645        status = p.read(&uct,sizeof(uct));
1646        rcsw.message.sSubAddress.digits[digitCount] = (uint8_t) uct;
1647    }
1648
1649    status = p.readInt32(&t);
1650    rcsw.message.uBearerDataLen = (int) t;
1651
1652    digitLimit = MIN((rcsw.message.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
1653
1654    for(digitCount = 0 ; digitCount < digitLimit; digitCount ++) {
1655        status = p.read(&uct, sizeof(uct));
1656        rcsw.message.aBearerData[digitCount] = (uint8_t) uct;
1657    }
1658
1659    if (status != NO_ERROR) {
1660        goto invalid;
1661    }
1662
1663    startRequest;
1664    appendPrintBuf("%sstatus=%d, message.uTeleserviceID=%d, message.bIsServicePresent=%d, \
1665            message.uServicecategory=%d, message.sAddress.digit_mode=%d, \
1666            message.sAddress.number_mode=%d, \
1667            message.sAddress.number_type=%d, ",
1668            printBuf, rcsw.status, rcsw.message.uTeleserviceID, rcsw.message.bIsServicePresent,
1669            rcsw.message.uServicecategory, rcsw.message.sAddress.digit_mode,
1670            rcsw.message.sAddress.number_mode,
1671            rcsw.message.sAddress.number_type);
1672    closeRequest;
1673
1674    printRequest(pRI->token, pRI->pCI->requestNumber);
1675
1676    CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw),pRI, pRI->socket_id);
1677
1678#ifdef MEMSET_FREED
1679    memset(&rcsw, 0, sizeof(rcsw));
1680#endif
1681
1682    return;
1683
1684invalid:
1685    invalidCommandBlock(pRI);
1686    return;
1687
1688}
1689
1690// For backwards compatibility in RIL_REQUEST_SETUP_DATA_CALL.
1691// Version 4 of the RIL interface adds a new PDP type parameter to support
1692// IPv6 and dual-stack PDP contexts. When dealing with a previous version of
1693// RIL, remove the parameter from the request.
1694static void dispatchDataCall(Parcel& p, RequestInfo *pRI) {
1695    // In RIL v3, REQUEST_SETUP_DATA_CALL takes 6 parameters.
1696    const int numParamsRilV3 = 6;
1697
1698    // The first bytes of the RIL parcel contain the request number and the
1699    // serial number - see processCommandBuffer(). Copy them over too.
1700    int pos = p.dataPosition();
1701
1702    int numParams = p.readInt32();
1703    if (s_callbacks.version < 4 && numParams > numParamsRilV3) {
1704      Parcel p2;
1705      p2.appendFrom(&p, 0, pos);
1706      p2.writeInt32(numParamsRilV3);
1707      for(int i = 0; i < numParamsRilV3; i++) {
1708        p2.writeString16(p.readString16());
1709      }
1710      p2.setDataPosition(pos);
1711      dispatchStrings(p2, pRI);
1712    } else {
1713      p.setDataPosition(pos);
1714      dispatchStrings(p, pRI);
1715    }
1716}
1717
1718// For backwards compatibility with RILs that dont support RIL_REQUEST_VOICE_RADIO_TECH.
1719// When all RILs handle this request, this function can be removed and
1720// the request can be sent directly to the RIL using dispatchVoid.
1721static void dispatchVoiceRadioTech(Parcel& p, RequestInfo *pRI) {
1722    RIL_RadioState state = CALL_ONSTATEREQUEST((RIL_SOCKET_ID)pRI->socket_id);
1723
1724    if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) {
1725        RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1726    }
1727
1728    // RILs that support RADIO_STATE_ON should support this request.
1729    if (RADIO_STATE_ON == state) {
1730        dispatchVoid(p, pRI);
1731        return;
1732    }
1733
1734    // For Older RILs, that do not support RADIO_STATE_ON, assume that they
1735    // will not support this new request either and decode Voice Radio Technology
1736    // from Radio State
1737    voiceRadioTech = decodeVoiceRadioTechnology(state);
1738
1739    if (voiceRadioTech < 0)
1740        RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0);
1741    else
1742        RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &voiceRadioTech, sizeof(int));
1743}
1744
1745// For backwards compatibility in RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:.
1746// When all RILs handle this request, this function can be removed and
1747// the request can be sent directly to the RIL using dispatchVoid.
1748static void dispatchCdmaSubscriptionSource(Parcel& p, RequestInfo *pRI) {
1749    RIL_RadioState state = CALL_ONSTATEREQUEST((RIL_SOCKET_ID)pRI->socket_id);
1750
1751    if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) {
1752        RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1753    }
1754
1755    // RILs that support RADIO_STATE_ON should support this request.
1756    if (RADIO_STATE_ON == state) {
1757        dispatchVoid(p, pRI);
1758        return;
1759    }
1760
1761    // For Older RILs, that do not support RADIO_STATE_ON, assume that they
1762    // will not support this new request either and decode CDMA Subscription Source
1763    // from Radio State
1764    cdmaSubscriptionSource = decodeCdmaSubscriptionSource(state);
1765
1766    if (cdmaSubscriptionSource < 0)
1767        RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0);
1768    else
1769        RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &cdmaSubscriptionSource, sizeof(int));
1770}
1771
1772static void dispatchSetInitialAttachApn(Parcel &p, RequestInfo *pRI)
1773{
1774    RIL_InitialAttachApn pf;
1775    int32_t  t;
1776    status_t status;
1777
1778    memset(&pf, 0, sizeof(pf));
1779
1780    pf.apn = strdupReadString(p);
1781    pf.protocol = strdupReadString(p);
1782
1783    status = p.readInt32(&t);
1784    pf.authtype = (int) t;
1785
1786    pf.username = strdupReadString(p);
1787    pf.password = strdupReadString(p);
1788
1789    startRequest;
1790    appendPrintBuf("%sapn=%s, protocol=%s, authtype=%d, username=%s, password=%s",
1791            printBuf, pf.apn, pf.protocol, pf.authtype, pf.username, pf.password);
1792    closeRequest;
1793    printRequest(pRI->token, pRI->pCI->requestNumber);
1794
1795    if (status != NO_ERROR) {
1796        goto invalid;
1797    }
1798    CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, pRI->socket_id);
1799
1800#ifdef MEMSET_FREED
1801    memsetString(pf.apn);
1802    memsetString(pf.protocol);
1803    memsetString(pf.username);
1804    memsetString(pf.password);
1805#endif
1806
1807    free(pf.apn);
1808    free(pf.protocol);
1809    free(pf.username);
1810    free(pf.password);
1811
1812#ifdef MEMSET_FREED
1813    memset(&pf, 0, sizeof(pf));
1814#endif
1815
1816    return;
1817invalid:
1818    invalidCommandBlock(pRI);
1819    return;
1820}
1821
1822static void dispatchNVReadItem(Parcel &p, RequestInfo *pRI) {
1823    RIL_NV_ReadItem nvri;
1824    int32_t  t;
1825    status_t status;
1826
1827    memset(&nvri, 0, sizeof(nvri));
1828
1829    status = p.readInt32(&t);
1830    nvri.itemID = (RIL_NV_Item) t;
1831
1832    if (status != NO_ERROR) {
1833        goto invalid;
1834    }
1835
1836    startRequest;
1837    appendPrintBuf("%snvri.itemID=%d, ", printBuf, nvri.itemID);
1838    closeRequest;
1839
1840    printRequest(pRI->token, pRI->pCI->requestNumber);
1841
1842    CALL_ONREQUEST(pRI->pCI->requestNumber, &nvri, sizeof(nvri), pRI, pRI->socket_id);
1843
1844#ifdef MEMSET_FREED
1845    memset(&nvri, 0, sizeof(nvri));
1846#endif
1847
1848    return;
1849
1850invalid:
1851    invalidCommandBlock(pRI);
1852    return;
1853}
1854
1855static void dispatchNVWriteItem(Parcel &p, RequestInfo *pRI) {
1856    RIL_NV_WriteItem nvwi;
1857    int32_t  t;
1858    status_t status;
1859
1860    memset(&nvwi, 0, sizeof(nvwi));
1861
1862    status = p.readInt32(&t);
1863    nvwi.itemID = (RIL_NV_Item) t;
1864
1865    nvwi.value = strdupReadString(p);
1866
1867    if (status != NO_ERROR || nvwi.value == NULL) {
1868        goto invalid;
1869    }
1870
1871    startRequest;
1872    appendPrintBuf("%snvwi.itemID=%d, value=%s, ", printBuf, nvwi.itemID,
1873            nvwi.value);
1874    closeRequest;
1875
1876    printRequest(pRI->token, pRI->pCI->requestNumber);
1877
1878    CALL_ONREQUEST(pRI->pCI->requestNumber, &nvwi, sizeof(nvwi), pRI, pRI->socket_id);
1879
1880#ifdef MEMSET_FREED
1881    memsetString(nvwi.value);
1882#endif
1883
1884    free(nvwi.value);
1885
1886#ifdef MEMSET_FREED
1887    memset(&nvwi, 0, sizeof(nvwi));
1888#endif
1889
1890    return;
1891
1892invalid:
1893    invalidCommandBlock(pRI);
1894    return;
1895}
1896
1897
1898static void dispatchUiccSubscripton(Parcel &p, RequestInfo *pRI) {
1899    RIL_SelectUiccSub uicc_sub;
1900    status_t status;
1901    int32_t  t;
1902    memset(&uicc_sub, 0, sizeof(uicc_sub));
1903
1904    status = p.readInt32(&t);
1905    if (status != NO_ERROR) {
1906        goto invalid;
1907    }
1908    uicc_sub.slot = (int) t;
1909
1910    status = p.readInt32(&t);
1911    if (status != NO_ERROR) {
1912        goto invalid;
1913    }
1914    uicc_sub.app_index = (int) t;
1915
1916    status = p.readInt32(&t);
1917    if (status != NO_ERROR) {
1918        goto invalid;
1919    }
1920    uicc_sub.sub_type = (RIL_SubscriptionType) t;
1921
1922    status = p.readInt32(&t);
1923    if (status != NO_ERROR) {
1924        goto invalid;
1925    }
1926    uicc_sub.act_status = (RIL_UiccSubActStatus) t;
1927
1928    startRequest;
1929    appendPrintBuf("slot=%d, app_index=%d, act_status = %d", uicc_sub.slot, uicc_sub.app_index,
1930            uicc_sub.act_status);
1931    RLOGD("dispatchUiccSubscription, slot=%d, app_index=%d, act_status = %d", uicc_sub.slot,
1932            uicc_sub.app_index, uicc_sub.act_status);
1933    closeRequest;
1934    printRequest(pRI->token, pRI->pCI->requestNumber);
1935
1936    CALL_ONREQUEST(pRI->pCI->requestNumber, &uicc_sub, sizeof(uicc_sub), pRI, pRI->socket_id);
1937
1938#ifdef MEMSET_FREED
1939    memset(&uicc_sub, 0, sizeof(uicc_sub));
1940#endif
1941    return;
1942
1943invalid:
1944    invalidCommandBlock(pRI);
1945    return;
1946}
1947
1948static void dispatchSimAuthentication(Parcel &p, RequestInfo *pRI)
1949{
1950    RIL_SimAuthentication pf;
1951    int32_t  t;
1952    status_t status;
1953
1954    memset(&pf, 0, sizeof(pf));
1955
1956    status = p.readInt32(&t);
1957    pf.authContext = (int) t;
1958    pf.authData = strdupReadString(p);
1959    pf.aid = strdupReadString(p);
1960
1961    startRequest;
1962    appendPrintBuf("authContext=%s, authData=%s, aid=%s", pf.authContext, pf.authData, pf.aid);
1963    closeRequest;
1964    printRequest(pRI->token, pRI->pCI->requestNumber);
1965
1966    if (status != NO_ERROR) {
1967        goto invalid;
1968    }
1969    CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, pRI->socket_id);
1970
1971#ifdef MEMSET_FREED
1972    memsetString(pf.authData);
1973    memsetString(pf.aid);
1974#endif
1975
1976    free(pf.authData);
1977    free(pf.aid);
1978
1979#ifdef MEMSET_FREED
1980    memset(&pf, 0, sizeof(pf));
1981#endif
1982
1983    return;
1984invalid:
1985    invalidCommandBlock(pRI);
1986    return;
1987}
1988
1989static void dispatchDataProfile(Parcel &p, RequestInfo *pRI) {
1990    int32_t t;
1991    status_t status;
1992    int32_t num;
1993
1994    status = p.readInt32(&num);
1995    if (status != NO_ERROR || num < 0) {
1996        goto invalid;
1997    }
1998
1999    {
2000        RIL_DataProfileInfo *dataProfiles =
2001                (RIL_DataProfileInfo *)calloc(num, sizeof(RIL_DataProfileInfo));
2002        if (dataProfiles == NULL) {
2003            RLOGE("Memory allocation failed for request %s",
2004                    requestToString(pRI->pCI->requestNumber));
2005            return;
2006        }
2007        RIL_DataProfileInfo **dataProfilePtrs =
2008                (RIL_DataProfileInfo **)calloc(num, sizeof(RIL_DataProfileInfo *));
2009        if (dataProfilePtrs == NULL) {
2010            RLOGE("Memory allocation failed for request %s",
2011                    requestToString(pRI->pCI->requestNumber));
2012            free(dataProfiles);
2013            return;
2014        }
2015
2016        startRequest;
2017        for (int i = 0 ; i < num ; i++ ) {
2018            dataProfilePtrs[i] = &dataProfiles[i];
2019
2020            status = p.readInt32(&t);
2021            dataProfiles[i].profileId = (int) t;
2022
2023            dataProfiles[i].apn = strdupReadString(p);
2024            dataProfiles[i].protocol = strdupReadString(p);
2025            status = p.readInt32(&t);
2026            dataProfiles[i].authType = (int) t;
2027
2028            dataProfiles[i].user = strdupReadString(p);
2029            dataProfiles[i].password = strdupReadString(p);
2030
2031            status = p.readInt32(&t);
2032            dataProfiles[i].type = (int) t;
2033
2034            status = p.readInt32(&t);
2035            dataProfiles[i].maxConnsTime = (int) t;
2036            status = p.readInt32(&t);
2037            dataProfiles[i].maxConns = (int) t;
2038            status = p.readInt32(&t);
2039            dataProfiles[i].waitTime = (int) t;
2040
2041            status = p.readInt32(&t);
2042            dataProfiles[i].enabled = (int) t;
2043
2044            appendPrintBuf("%s [%d: profileId=%d, apn =%s, protocol =%s, authType =%d, \
2045                  user =%s, password =%s, type =%d, maxConnsTime =%d, maxConns =%d, \
2046                  waitTime =%d, enabled =%d]", printBuf, i, dataProfiles[i].profileId,
2047                  dataProfiles[i].apn, dataProfiles[i].protocol, dataProfiles[i].authType,
2048                  dataProfiles[i].user, dataProfiles[i].password, dataProfiles[i].type,
2049                  dataProfiles[i].maxConnsTime, dataProfiles[i].maxConns,
2050                  dataProfiles[i].waitTime, dataProfiles[i].enabled);
2051        }
2052        closeRequest;
2053        printRequest(pRI->token, pRI->pCI->requestNumber);
2054
2055        if (status != NO_ERROR) {
2056            free(dataProfiles);
2057            free(dataProfilePtrs);
2058            goto invalid;
2059        }
2060        CALL_ONREQUEST(pRI->pCI->requestNumber,
2061                              dataProfilePtrs,
2062                              num * sizeof(RIL_DataProfileInfo *),
2063                              pRI, pRI->socket_id);
2064
2065#ifdef MEMSET_FREED
2066        memset(dataProfiles, 0, num * sizeof(RIL_DataProfileInfo));
2067        memset(dataProfilePtrs, 0, num * sizeof(RIL_DataProfileInfo *));
2068#endif
2069        free(dataProfiles);
2070        free(dataProfilePtrs);
2071    }
2072
2073    return;
2074
2075invalid:
2076    invalidCommandBlock(pRI);
2077    return;
2078}
2079
2080static void dispatchRadioCapability(Parcel &p, RequestInfo *pRI){
2081    RIL_RadioCapability rc;
2082    int32_t t;
2083    status_t status;
2084
2085    memset (&rc, 0, sizeof(RIL_RadioCapability));
2086
2087    status = p.readInt32(&t);
2088    rc.version = (int)t;
2089    if (status != NO_ERROR) {
2090        goto invalid;
2091    }
2092
2093    status = p.readInt32(&t);
2094    rc.session= (int)t;
2095    if (status != NO_ERROR) {
2096        goto invalid;
2097    }
2098
2099    status = p.readInt32(&t);
2100    rc.phase= (int)t;
2101    if (status != NO_ERROR) {
2102        goto invalid;
2103    }
2104
2105    status = p.readInt32(&t);
2106    rc.rat = (int)t;
2107    if (status != NO_ERROR) {
2108        goto invalid;
2109    }
2110
2111    status = readStringFromParcelInplace(p, rc.logicalModemUuid, sizeof(rc.logicalModemUuid));
2112    if (status != NO_ERROR) {
2113        goto invalid;
2114    }
2115
2116    status = p.readInt32(&t);
2117    rc.status = (int)t;
2118
2119    if (status != NO_ERROR) {
2120        goto invalid;
2121    }
2122
2123    startRequest;
2124    appendPrintBuf("%s [version:%d, session:%d, phase:%d, rat:%d, \
2125            logicalModemUuid:%s, status:%d", printBuf, rc.version, rc.session,
2126            rc.phase, rc.rat, rc.logicalModemUuid, rc.session);
2127
2128    closeRequest;
2129    printRequest(pRI->token, pRI->pCI->requestNumber);
2130
2131    CALL_ONREQUEST(pRI->pCI->requestNumber,
2132                &rc,
2133                sizeof(RIL_RadioCapability),
2134                pRI, pRI->socket_id);
2135    return;
2136invalid:
2137    invalidCommandBlock(pRI);
2138    return;
2139}
2140
2141/**
2142 * Callee expects const RIL_CarrierRestrictions *
2143 */
2144static void dispatchCarrierRestrictions(Parcel &p, RequestInfo *pRI) {
2145    RIL_CarrierRestrictions cr;
2146    RIL_Carrier * allowed_carriers = NULL;
2147    RIL_Carrier * excluded_carriers = NULL;
2148    int32_t t;
2149    status_t status;
2150
2151    memset(&cr, 0, sizeof(RIL_CarrierRestrictions));
2152
2153    if (s_callbacks.version < 14) {
2154        RLOGE("Unsuppoted RIL version %d, min version expected %d",
2155              s_callbacks.version, 14);
2156        RIL_onRequestComplete(pRI, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
2157        return;
2158    }
2159
2160    status = p.readInt32(&t);
2161    if (status != NO_ERROR) {
2162        goto invalid;
2163    }
2164    allowed_carriers = (RIL_Carrier *)calloc(t, sizeof(RIL_Carrier));
2165    if (allowed_carriers == NULL) {
2166        RLOGE("Memory allocation failed for request %s", requestToString(pRI->pCI->requestNumber));
2167        goto exit;
2168    }
2169    cr.len_allowed_carriers = t;
2170    cr.allowed_carriers = allowed_carriers;
2171
2172    status = p.readInt32(&t);
2173    if (status != NO_ERROR) {
2174        goto invalid;
2175    }
2176    excluded_carriers = (RIL_Carrier *)calloc(t, sizeof(RIL_Carrier));
2177    if (excluded_carriers == NULL) {
2178        RLOGE("Memory allocation failed for request %s", requestToString(pRI->pCI->requestNumber));
2179        goto exit;
2180    }
2181    cr.len_excluded_carriers = t;
2182    cr.excluded_carriers = excluded_carriers;
2183
2184    startRequest;
2185    appendPrintBuf("%s len_allowed_carriers:%d, len_excluded_carriers:%d,",
2186                   printBuf, cr.len_allowed_carriers, cr.len_excluded_carriers);
2187
2188    appendPrintBuf("%s allowed_carriers:", printBuf);
2189    for (int32_t i = 0; i < cr.len_allowed_carriers; i++) {
2190        RIL_Carrier *p_cr = allowed_carriers + i;
2191        p_cr->mcc = strdupReadString(p);
2192        p_cr->mnc = strdupReadString(p);
2193        status = p.readInt32(&t);
2194        p_cr->match_type = static_cast<RIL_CarrierMatchType>(t);
2195        if (status != NO_ERROR) {
2196            goto invalid;
2197        }
2198        p_cr->match_data = strdupReadString(p);
2199        appendPrintBuf("%s [%d mcc:%s, mnc:%s, match_type:%d, match_data:%s],",
2200                       printBuf, i, p_cr->mcc, p_cr->mnc, p_cr->match_type, p_cr->match_data);
2201    }
2202
2203    for (int32_t i = 0; i < cr.len_excluded_carriers; i++) {
2204        RIL_Carrier *p_cr = excluded_carriers + i;
2205        p_cr->mcc = strdupReadString(p);
2206        p_cr->mnc = strdupReadString(p);
2207        status = p.readInt32(&t);
2208        p_cr->match_type = static_cast<RIL_CarrierMatchType>(t);
2209        if (status != NO_ERROR) {
2210            goto invalid;
2211        }
2212        p_cr->match_data = strdupReadString(p);
2213        appendPrintBuf("%s [%d mcc:%s, mnc:%s, match_type:%d, match_data:%s],",
2214                       printBuf, i, p_cr->mcc, p_cr->mnc, p_cr->match_type, p_cr->match_data);
2215    }
2216
2217    closeRequest;
2218    printRequest(pRI->token, pRI->pCI->requestNumber);
2219
2220    CALL_ONREQUEST(pRI->pCI->requestNumber,
2221                &cr,
2222                sizeof(RIL_CarrierRestrictions),
2223                pRI, pRI->socket_id);
2224
2225    goto exit;
2226
2227invalid:
2228    invalidCommandBlock(pRI);
2229    RIL_onRequestComplete(pRI, RIL_E_INVALID_ARGUMENTS, NULL, 0);
2230exit:
2231    if (allowed_carriers != NULL) {
2232        free(allowed_carriers);
2233    }
2234    if (excluded_carriers != NULL) {
2235        free(excluded_carriers);
2236    }
2237    return;
2238}
2239
2240static int
2241blockingWrite(int fd, const void *buffer, size_t len) {
2242    size_t writeOffset = 0;
2243    const uint8_t *toWrite;
2244
2245    toWrite = (const uint8_t *)buffer;
2246
2247    while (writeOffset < len) {
2248        ssize_t written;
2249        do {
2250            written = write (fd, toWrite + writeOffset,
2251                                len - writeOffset);
2252        } while (written < 0 && ((errno == EINTR) || (errno == EAGAIN)));
2253
2254        if (written >= 0) {
2255            writeOffset += written;
2256        } else {   // written < 0
2257            RLOGE ("RIL Response: unexpected error on write errno:%d", errno);
2258            close(fd);
2259            return -1;
2260        }
2261    }
2262#if VDBG
2263    RLOGE("RIL Response bytes written:%d", writeOffset);
2264#endif
2265    return 0;
2266}
2267
2268static int
2269sendResponseRaw (const void *data, size_t dataSize, RIL_SOCKET_ID socket_id) {
2270    int fd = s_ril_param_socket.fdCommand;
2271    int ret;
2272    uint32_t header;
2273    pthread_mutex_t * writeMutexHook = &s_writeMutex;
2274
2275#if VDBG
2276    RLOGE("Send Response to %s", rilSocketIdToString(socket_id));
2277#endif
2278
2279#if (SIM_COUNT >= 2)
2280    if (socket_id == RIL_SOCKET_2) {
2281        fd = s_ril_param_socket2.fdCommand;
2282        writeMutexHook = &s_writeMutex_socket2;
2283    }
2284#if (SIM_COUNT >= 3)
2285    else if (socket_id == RIL_SOCKET_3) {
2286        fd = s_ril_param_socket3.fdCommand;
2287        writeMutexHook = &s_writeMutex_socket3;
2288    }
2289#endif
2290#if (SIM_COUNT >= 4)
2291    else if (socket_id == RIL_SOCKET_4) {
2292        fd = s_ril_param_socket4.fdCommand;
2293        writeMutexHook = &s_writeMutex_socket4;
2294    }
2295#endif
2296#endif
2297    if (fd < 0) {
2298        return -1;
2299    }
2300
2301    if (dataSize > MAX_COMMAND_BYTES) {
2302        RLOGE("RIL: packet larger than %u (%u)",
2303                MAX_COMMAND_BYTES, (unsigned int )dataSize);
2304
2305        return -1;
2306    }
2307
2308    pthread_mutex_lock(writeMutexHook);
2309
2310    header = htonl(dataSize);
2311
2312    ret = blockingWrite(fd, (void *)&header, sizeof(header));
2313
2314    if (ret < 0) {
2315        pthread_mutex_unlock(writeMutexHook);
2316        return ret;
2317    }
2318
2319    ret = blockingWrite(fd, data, dataSize);
2320
2321    if (ret < 0) {
2322        pthread_mutex_unlock(writeMutexHook);
2323        return ret;
2324    }
2325
2326    pthread_mutex_unlock(writeMutexHook);
2327
2328    return 0;
2329}
2330
2331static int
2332sendResponse (Parcel &p, RIL_SOCKET_ID socket_id) {
2333    printResponse;
2334    return sendResponseRaw(p.data(), p.dataSize(), socket_id);
2335}
2336
2337/** response is an int* pointing to an array of ints */
2338
2339static int
2340responseInts(Parcel &p, void *response, size_t responselen) {
2341    int numInts;
2342
2343    if (response == NULL && responselen != 0) {
2344        RLOGE("invalid response: NULL");
2345        return RIL_ERRNO_INVALID_RESPONSE;
2346    }
2347    if (responselen % sizeof(int) != 0) {
2348        RLOGE("responseInts: invalid response length %d expected multiple of %d\n",
2349            (int)responselen, (int)sizeof(int));
2350        return RIL_ERRNO_INVALID_RESPONSE;
2351    }
2352
2353    int *p_int = (int *) response;
2354
2355    numInts = responselen / sizeof(int);
2356    p.writeInt32 (numInts);
2357
2358    /* each int*/
2359    startResponse;
2360    for (int i = 0 ; i < numInts ; i++) {
2361        appendPrintBuf("%s%d,", printBuf, p_int[i]);
2362        p.writeInt32(p_int[i]);
2363    }
2364    removeLastChar;
2365    closeResponse;
2366
2367    return 0;
2368}
2369
2370// Response is an int or RIL_LastCallFailCauseInfo.
2371// Currently, only Shamu plans to use RIL_LastCallFailCauseInfo.
2372// TODO(yjl): Let all implementations use RIL_LastCallFailCauseInfo.
2373static int responseFailCause(Parcel &p, void *response, size_t responselen) {
2374    if (response == NULL && responselen != 0) {
2375        RLOGE("invalid response: NULL");
2376        return RIL_ERRNO_INVALID_RESPONSE;
2377    }
2378
2379    if (responselen == sizeof(int)) {
2380      startResponse;
2381      int *p_int = (int *) response;
2382      appendPrintBuf("%s%d,", printBuf, p_int[0]);
2383      p.writeInt32(p_int[0]);
2384      removeLastChar;
2385      closeResponse;
2386    } else if (responselen == sizeof(RIL_LastCallFailCauseInfo)) {
2387      startResponse;
2388      RIL_LastCallFailCauseInfo *p_fail_cause_info = (RIL_LastCallFailCauseInfo *) response;
2389      appendPrintBuf("%s[cause_code=%d,vendor_cause=%s]", printBuf, p_fail_cause_info->cause_code,
2390                     p_fail_cause_info->vendor_cause);
2391      p.writeInt32(p_fail_cause_info->cause_code);
2392      writeStringToParcel(p, p_fail_cause_info->vendor_cause);
2393      removeLastChar;
2394      closeResponse;
2395    } else {
2396      RLOGE("responseFailCause: invalid response length %d expected an int or "
2397            "RIL_LastCallFailCauseInfo", (int)responselen);
2398      return RIL_ERRNO_INVALID_RESPONSE;
2399    }
2400
2401    return 0;
2402}
2403
2404/** response is a char **, pointing to an array of char *'s
2405    The parcel will begin with the version */
2406static int responseStringsWithVersion(int version, Parcel &p, void *response, size_t responselen) {
2407    p.writeInt32(version);
2408    return responseStrings(p, response, responselen);
2409}
2410
2411/** response is a char **, pointing to an array of char *'s */
2412static int responseStrings(Parcel &p, void *response, size_t responselen) {
2413    int numStrings;
2414
2415    if (response == NULL && responselen != 0) {
2416        RLOGE("invalid response: NULL");
2417        return RIL_ERRNO_INVALID_RESPONSE;
2418    }
2419    if (responselen % sizeof(char *) != 0) {
2420        RLOGE("responseStrings: invalid response length %d expected multiple of %d\n",
2421            (int)responselen, (int)sizeof(char *));
2422        return RIL_ERRNO_INVALID_RESPONSE;
2423    }
2424
2425    if (response == NULL) {
2426        p.writeInt32 (0);
2427    } else {
2428        char **p_cur = (char **) response;
2429
2430        numStrings = responselen / sizeof(char *);
2431        p.writeInt32 (numStrings);
2432
2433        /* each string*/
2434        startResponse;
2435        for (int i = 0 ; i < numStrings ; i++) {
2436            appendPrintBuf("%s%s,", printBuf, (char*)p_cur[i]);
2437            writeStringToParcel (p, p_cur[i]);
2438        }
2439        removeLastChar;
2440        closeResponse;
2441    }
2442    return 0;
2443}
2444
2445
2446/**
2447 * NULL strings are accepted
2448 * FIXME currently ignores responselen
2449 */
2450static int responseString(Parcel &p, void *response, size_t responselen) {
2451    /* one string only */
2452    startResponse;
2453    appendPrintBuf("%s%s", printBuf, (char*)response);
2454    closeResponse;
2455
2456    writeStringToParcel(p, (const char *)response);
2457
2458    return 0;
2459}
2460
2461static int responseVoid(Parcel &p, void *response, size_t responselen) {
2462    startResponse;
2463    removeLastChar;
2464    return 0;
2465}
2466
2467static int responseCallList(Parcel &p, void *response, size_t responselen) {
2468    int num;
2469
2470    if (response == NULL && responselen != 0) {
2471        RLOGE("invalid response: NULL");
2472        return RIL_ERRNO_INVALID_RESPONSE;
2473    }
2474
2475    if (responselen % sizeof (RIL_Call *) != 0) {
2476        RLOGE("responseCallList: invalid response length %d expected multiple of %d\n",
2477            (int)responselen, (int)sizeof (RIL_Call *));
2478        return RIL_ERRNO_INVALID_RESPONSE;
2479    }
2480
2481    startResponse;
2482    /* number of call info's */
2483    num = responselen / sizeof(RIL_Call *);
2484    p.writeInt32(num);
2485
2486    for (int i = 0 ; i < num ; i++) {
2487        RIL_Call *p_cur = ((RIL_Call **) response)[i];
2488        /* each call info */
2489        p.writeInt32(p_cur->state);
2490        p.writeInt32(p_cur->index);
2491        p.writeInt32(p_cur->toa);
2492        p.writeInt32(p_cur->isMpty);
2493        p.writeInt32(p_cur->isMT);
2494        p.writeInt32(p_cur->als);
2495        p.writeInt32(p_cur->isVoice);
2496        p.writeInt32(p_cur->isVoicePrivacy);
2497        writeStringToParcel(p, p_cur->number);
2498        p.writeInt32(p_cur->numberPresentation);
2499        writeStringToParcel(p, p_cur->name);
2500        p.writeInt32(p_cur->namePresentation);
2501        // Remove when partners upgrade to version 3
2502        if ((s_callbacks.version < 3) || (p_cur->uusInfo == NULL || p_cur->uusInfo->uusData == NULL)) {
2503            p.writeInt32(0); /* UUS Information is absent */
2504        } else {
2505            RIL_UUS_Info *uusInfo = p_cur->uusInfo;
2506            p.writeInt32(1); /* UUS Information is present */
2507            p.writeInt32(uusInfo->uusType);
2508            p.writeInt32(uusInfo->uusDcs);
2509            p.writeInt32(uusInfo->uusLength);
2510            p.write(uusInfo->uusData, uusInfo->uusLength);
2511        }
2512        appendPrintBuf("%s[id=%d,%s,toa=%d,",
2513            printBuf,
2514            p_cur->index,
2515            callStateToString(p_cur->state),
2516            p_cur->toa);
2517        appendPrintBuf("%s%s,%s,als=%d,%s,%s,",
2518            printBuf,
2519            (p_cur->isMpty)?"conf":"norm",
2520            (p_cur->isMT)?"mt":"mo",
2521            p_cur->als,
2522            (p_cur->isVoice)?"voc":"nonvoc",
2523            (p_cur->isVoicePrivacy)?"evp":"noevp");
2524        appendPrintBuf("%s%s,cli=%d,name='%s',%d]",
2525            printBuf,
2526            p_cur->number,
2527            p_cur->numberPresentation,
2528            p_cur->name,
2529            p_cur->namePresentation);
2530    }
2531    removeLastChar;
2532    closeResponse;
2533
2534    return 0;
2535}
2536
2537static int responseSMS(Parcel &p, void *response, size_t responselen) {
2538    if (response == NULL) {
2539        RLOGE("invalid response: NULL");
2540        return RIL_ERRNO_INVALID_RESPONSE;
2541    }
2542
2543    if (responselen != sizeof (RIL_SMS_Response) ) {
2544        RLOGE("invalid response length %d expected %d",
2545                (int)responselen, (int)sizeof (RIL_SMS_Response));
2546        return RIL_ERRNO_INVALID_RESPONSE;
2547    }
2548
2549    RIL_SMS_Response *p_cur = (RIL_SMS_Response *) response;
2550
2551    p.writeInt32(p_cur->messageRef);
2552    writeStringToParcel(p, p_cur->ackPDU);
2553    p.writeInt32(p_cur->errorCode);
2554
2555    startResponse;
2556    appendPrintBuf("%s%d,%s,%d", printBuf, p_cur->messageRef,
2557        (char*)p_cur->ackPDU, p_cur->errorCode);
2558    closeResponse;
2559
2560    return 0;
2561}
2562
2563static int responseDataCallListV4(Parcel &p, void *response, size_t responselen)
2564{
2565    if (response == NULL && responselen != 0) {
2566        RLOGE("invalid response: NULL");
2567        return RIL_ERRNO_INVALID_RESPONSE;
2568    }
2569
2570    if (responselen % sizeof(RIL_Data_Call_Response_v4) != 0) {
2571        RLOGE("responseDataCallListV4: invalid response length %d expected multiple of %d",
2572                (int)responselen, (int)sizeof(RIL_Data_Call_Response_v4));
2573        return RIL_ERRNO_INVALID_RESPONSE;
2574    }
2575
2576    // Write version
2577    p.writeInt32(4);
2578
2579    int num = responselen / sizeof(RIL_Data_Call_Response_v4);
2580    p.writeInt32(num);
2581
2582    RIL_Data_Call_Response_v4 *p_cur = (RIL_Data_Call_Response_v4 *) response;
2583    startResponse;
2584    int i;
2585    for (i = 0; i < num; i++) {
2586        p.writeInt32(p_cur[i].cid);
2587        p.writeInt32(p_cur[i].active);
2588        writeStringToParcel(p, p_cur[i].type);
2589        // apn is not used, so don't send.
2590        writeStringToParcel(p, p_cur[i].address);
2591        appendPrintBuf("%s[cid=%d,%s,%s,%s],", printBuf,
2592            p_cur[i].cid,
2593            (p_cur[i].active==0)?"down":"up",
2594            (char*)p_cur[i].type,
2595            (char*)p_cur[i].address);
2596    }
2597    removeLastChar;
2598    closeResponse;
2599
2600    return 0;
2601}
2602
2603static int responseDataCallListV6(Parcel &p, void *response, size_t responselen)
2604{
2605    if (response == NULL && responselen != 0) {
2606        RLOGE("invalid response: NULL");
2607        return RIL_ERRNO_INVALID_RESPONSE;
2608    }
2609
2610    if (responselen % sizeof(RIL_Data_Call_Response_v6) != 0) {
2611        RLOGE("responseDataCallListV6: invalid response length %d expected multiple of %d",
2612                (int)responselen, (int)sizeof(RIL_Data_Call_Response_v6));
2613        return RIL_ERRNO_INVALID_RESPONSE;
2614    }
2615
2616    // Write version
2617    p.writeInt32(6);
2618
2619    int num = responselen / sizeof(RIL_Data_Call_Response_v6);
2620    p.writeInt32(num);
2621
2622    RIL_Data_Call_Response_v6 *p_cur = (RIL_Data_Call_Response_v6 *) response;
2623    startResponse;
2624    int i;
2625    for (i = 0; i < num; i++) {
2626        p.writeInt32((int)p_cur[i].status);
2627        p.writeInt32(p_cur[i].suggestedRetryTime);
2628        p.writeInt32(p_cur[i].cid);
2629        p.writeInt32(p_cur[i].active);
2630        writeStringToParcel(p, p_cur[i].type);
2631        writeStringToParcel(p, p_cur[i].ifname);
2632        writeStringToParcel(p, p_cur[i].addresses);
2633        writeStringToParcel(p, p_cur[i].dnses);
2634        writeStringToParcel(p, p_cur[i].gateways);
2635        appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s],", printBuf,
2636            p_cur[i].status,
2637            p_cur[i].suggestedRetryTime,
2638            p_cur[i].cid,
2639            (p_cur[i].active==0)?"down":"up",
2640            (char*)p_cur[i].type,
2641            (char*)p_cur[i].ifname,
2642            (char*)p_cur[i].addresses,
2643            (char*)p_cur[i].dnses,
2644            (char*)p_cur[i].gateways);
2645    }
2646    removeLastChar;
2647    closeResponse;
2648
2649    return 0;
2650}
2651
2652static int responseDataCallListV9(Parcel &p, void *response, size_t responselen)
2653{
2654    if (response == NULL && responselen != 0) {
2655        RLOGE("invalid response: NULL");
2656        return RIL_ERRNO_INVALID_RESPONSE;
2657    }
2658
2659    if (responselen % sizeof(RIL_Data_Call_Response_v9) != 0) {
2660        RLOGE("responseDataCallListV9: invalid response length %d expected multiple of %d",
2661                (int)responselen, (int)sizeof(RIL_Data_Call_Response_v9));
2662        return RIL_ERRNO_INVALID_RESPONSE;
2663    }
2664
2665    // Write version
2666    p.writeInt32(10);
2667
2668    int num = responselen / sizeof(RIL_Data_Call_Response_v9);
2669    p.writeInt32(num);
2670
2671    RIL_Data_Call_Response_v9 *p_cur = (RIL_Data_Call_Response_v9 *) response;
2672    startResponse;
2673    int i;
2674    for (i = 0; i < num; i++) {
2675        p.writeInt32((int)p_cur[i].status);
2676        p.writeInt32(p_cur[i].suggestedRetryTime);
2677        p.writeInt32(p_cur[i].cid);
2678        p.writeInt32(p_cur[i].active);
2679        writeStringToParcel(p, p_cur[i].type);
2680        writeStringToParcel(p, p_cur[i].ifname);
2681        writeStringToParcel(p, p_cur[i].addresses);
2682        writeStringToParcel(p, p_cur[i].dnses);
2683        writeStringToParcel(p, p_cur[i].gateways);
2684        writeStringToParcel(p, p_cur[i].pcscf);
2685        appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s],", printBuf,
2686            p_cur[i].status,
2687            p_cur[i].suggestedRetryTime,
2688            p_cur[i].cid,
2689            (p_cur[i].active==0)?"down":"up",
2690            (char*)p_cur[i].type,
2691            (char*)p_cur[i].ifname,
2692            (char*)p_cur[i].addresses,
2693            (char*)p_cur[i].dnses,
2694            (char*)p_cur[i].gateways,
2695            (char*)p_cur[i].pcscf);
2696    }
2697    removeLastChar;
2698    closeResponse;
2699
2700    return 0;
2701}
2702
2703static int responseDataCallListV11(Parcel &p, void *response, size_t responselen) {
2704    if (response == NULL && responselen != 0) {
2705                RLOGE("invalid response: NULL");
2706                return RIL_ERRNO_INVALID_RESPONSE;
2707    }
2708
2709    if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) {
2710        RLOGE("invalid response length %d expected multiple of %d",
2711        (int)responselen, (int)sizeof(RIL_Data_Call_Response_v11));
2712        return RIL_ERRNO_INVALID_RESPONSE;
2713    }
2714
2715    // Write version
2716    p.writeInt32(11);
2717
2718    int num = responselen / sizeof(RIL_Data_Call_Response_v11);
2719    p.writeInt32(num);
2720
2721    RIL_Data_Call_Response_v11 *p_cur = (RIL_Data_Call_Response_v11 *) response;
2722    startResponse;
2723    int i;
2724    for (i = 0; i < num; i++) {
2725        p.writeInt32((int)p_cur[i].status);
2726        p.writeInt32(p_cur[i].suggestedRetryTime);
2727        p.writeInt32(p_cur[i].cid);
2728        p.writeInt32(p_cur[i].active);
2729        writeStringToParcel(p, p_cur[i].type);
2730        writeStringToParcel(p, p_cur[i].ifname);
2731        writeStringToParcel(p, p_cur[i].addresses);
2732        writeStringToParcel(p, p_cur[i].dnses);
2733        writeStringToParcel(p, p_cur[i].gateways);
2734        writeStringToParcel(p, p_cur[i].pcscf);
2735        p.writeInt32(p_cur[i].mtu);
2736        appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s,mtu=%d],", printBuf,
2737        p_cur[i].status,
2738        p_cur[i].suggestedRetryTime,
2739        p_cur[i].cid,
2740        (p_cur[i].active==0)?"down":"up",
2741        (char*)p_cur[i].type,
2742        (char*)p_cur[i].ifname,
2743        (char*)p_cur[i].addresses,
2744        (char*)p_cur[i].dnses,
2745        (char*)p_cur[i].gateways,
2746        (char*)p_cur[i].pcscf,
2747        p_cur[i].mtu);
2748    }
2749    removeLastChar;
2750    closeResponse;
2751
2752    return 0;
2753}
2754
2755static int responseDataCallList(Parcel &p, void *response, size_t responselen)
2756{
2757    if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
2758        if (s_callbacks.version < 5) {
2759            RLOGD("responseDataCallList: v4");
2760            return responseDataCallListV4(p, response, responselen);
2761        } else if (responselen % sizeof(RIL_Data_Call_Response_v6) == 0) {
2762            return responseDataCallListV6(p, response, responselen);
2763        } else if (responselen % sizeof(RIL_Data_Call_Response_v9) == 0) {
2764            return responseDataCallListV9(p, response, responselen);
2765        } else {
2766            return responseDataCallListV11(p, response, responselen);
2767        }
2768    } else { // RIL version >= 13
2769        if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) {
2770            RLOGE("Data structure expected is RIL_Data_Call_Response_v11");
2771            if (!isDebuggable()) {
2772                return RIL_ERRNO_INVALID_RESPONSE;
2773            } else {
2774                assert(0);
2775            }
2776        }
2777        return responseDataCallListV11(p, response, responselen);
2778    }
2779}
2780
2781static int responseSetupDataCall(Parcel &p, void *response, size_t responselen)
2782{
2783    if (s_callbacks.version < 5) {
2784        return responseStringsWithVersion(s_callbacks.version, p, response, responselen);
2785    } else {
2786        return responseDataCallList(p, response, responselen);
2787    }
2788}
2789
2790static int responseRaw(Parcel &p, void *response, size_t responselen) {
2791    if (response == NULL && responselen != 0) {
2792        RLOGE("invalid response: NULL with responselen != 0");
2793        return RIL_ERRNO_INVALID_RESPONSE;
2794    }
2795
2796    // The java code reads -1 size as null byte array
2797    if (response == NULL) {
2798        p.writeInt32(-1);
2799    } else {
2800        p.writeInt32(responselen);
2801        p.write(response, responselen);
2802    }
2803
2804    return 0;
2805}
2806
2807
2808static int responseSIM_IO(Parcel &p, void *response, size_t responselen) {
2809    if (response == NULL) {
2810        RLOGE("invalid response: NULL");
2811        return RIL_ERRNO_INVALID_RESPONSE;
2812    }
2813
2814    if (responselen != sizeof (RIL_SIM_IO_Response) ) {
2815        RLOGE("invalid response length was %d expected %d",
2816                (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
2817        return RIL_ERRNO_INVALID_RESPONSE;
2818    }
2819
2820    RIL_SIM_IO_Response *p_cur = (RIL_SIM_IO_Response *) response;
2821    p.writeInt32(p_cur->sw1);
2822    p.writeInt32(p_cur->sw2);
2823    writeStringToParcel(p, p_cur->simResponse);
2824
2825    startResponse;
2826    appendPrintBuf("%ssw1=0x%X,sw2=0x%X,%s", printBuf, p_cur->sw1, p_cur->sw2,
2827        (char*)p_cur->simResponse);
2828    closeResponse;
2829
2830
2831    return 0;
2832}
2833
2834static int responseCallForwards(Parcel &p, void *response, size_t responselen) {
2835    int num;
2836
2837    if (response == NULL && responselen != 0) {
2838        RLOGE("invalid response: NULL");
2839        return RIL_ERRNO_INVALID_RESPONSE;
2840    }
2841
2842    if (responselen % sizeof(RIL_CallForwardInfo *) != 0) {
2843        RLOGE("responseCallForwards: invalid response length %d expected multiple of %d",
2844                (int)responselen, (int)sizeof(RIL_CallForwardInfo *));
2845        return RIL_ERRNO_INVALID_RESPONSE;
2846    }
2847
2848    /* number of call info's */
2849    num = responselen / sizeof(RIL_CallForwardInfo *);
2850    p.writeInt32(num);
2851
2852    startResponse;
2853    for (int i = 0 ; i < num ; i++) {
2854        RIL_CallForwardInfo *p_cur = ((RIL_CallForwardInfo **) response)[i];
2855
2856        p.writeInt32(p_cur->status);
2857        p.writeInt32(p_cur->reason);
2858        p.writeInt32(p_cur->serviceClass);
2859        p.writeInt32(p_cur->toa);
2860        writeStringToParcel(p, p_cur->number);
2861        p.writeInt32(p_cur->timeSeconds);
2862        appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
2863            (p_cur->status==1)?"enable":"disable",
2864            p_cur->reason, p_cur->serviceClass, p_cur->toa,
2865            (char*)p_cur->number,
2866            p_cur->timeSeconds);
2867    }
2868    removeLastChar;
2869    closeResponse;
2870
2871    return 0;
2872}
2873
2874static int responseSsn(Parcel &p, void *response, size_t responselen) {
2875    if (response == NULL) {
2876        RLOGE("invalid response: NULL");
2877        return RIL_ERRNO_INVALID_RESPONSE;
2878    }
2879
2880    if (responselen != sizeof(RIL_SuppSvcNotification)) {
2881        RLOGE("invalid response length was %d expected %d",
2882                (int)responselen, (int)sizeof (RIL_SuppSvcNotification));
2883        return RIL_ERRNO_INVALID_RESPONSE;
2884    }
2885
2886    RIL_SuppSvcNotification *p_cur = (RIL_SuppSvcNotification *) response;
2887    p.writeInt32(p_cur->notificationType);
2888    p.writeInt32(p_cur->code);
2889    p.writeInt32(p_cur->index);
2890    p.writeInt32(p_cur->type);
2891    writeStringToParcel(p, p_cur->number);
2892
2893    startResponse;
2894    appendPrintBuf("%s%s,code=%d,id=%d,type=%d,%s", printBuf,
2895        (p_cur->notificationType==0)?"mo":"mt",
2896         p_cur->code, p_cur->index, p_cur->type,
2897        (char*)p_cur->number);
2898    closeResponse;
2899
2900    return 0;
2901}
2902
2903static int responseCellList(Parcel &p, void *response, size_t responselen) {
2904    int num;
2905
2906    if (response == NULL && responselen != 0) {
2907        RLOGE("invalid response: NULL");
2908        return RIL_ERRNO_INVALID_RESPONSE;
2909    }
2910
2911    if (responselen % sizeof (RIL_NeighboringCell *) != 0) {
2912        RLOGE("responseCellList: invalid response length %d expected multiple of %d\n",
2913            (int)responselen, (int)sizeof (RIL_NeighboringCell *));
2914        return RIL_ERRNO_INVALID_RESPONSE;
2915    }
2916
2917    startResponse;
2918    /* number of records */
2919    num = responselen / sizeof(RIL_NeighboringCell *);
2920    p.writeInt32(num);
2921
2922    for (int i = 0 ; i < num ; i++) {
2923        RIL_NeighboringCell *p_cur = ((RIL_NeighboringCell **) response)[i];
2924
2925        p.writeInt32(p_cur->rssi);
2926        writeStringToParcel (p, p_cur->cid);
2927
2928        appendPrintBuf("%s[cid=%s,rssi=%d],", printBuf,
2929            p_cur->cid, p_cur->rssi);
2930    }
2931    removeLastChar;
2932    closeResponse;
2933
2934    return 0;
2935}
2936
2937/**
2938 * Marshall the signalInfoRecord into the parcel if it exists.
2939 */
2940static void marshallSignalInfoRecord(Parcel &p,
2941            RIL_CDMA_SignalInfoRecord &p_signalInfoRecord) {
2942    p.writeInt32(p_signalInfoRecord.isPresent);
2943    p.writeInt32(p_signalInfoRecord.signalType);
2944    p.writeInt32(p_signalInfoRecord.alertPitch);
2945    p.writeInt32(p_signalInfoRecord.signal);
2946}
2947
2948static int responseCdmaInformationRecords(Parcel &p,
2949            void *response, size_t responselen) {
2950    int num;
2951    char* string8 = NULL;
2952    int buffer_lenght;
2953    RIL_CDMA_InformationRecord *infoRec;
2954
2955    if (response == NULL && responselen != 0) {
2956        RLOGE("invalid response: NULL");
2957        return RIL_ERRNO_INVALID_RESPONSE;
2958    }
2959
2960    if (responselen != sizeof (RIL_CDMA_InformationRecords)) {
2961        RLOGE("responseCdmaInformationRecords: invalid response length %d expected multiple of %d\n",
2962            (int)responselen, (int)sizeof (RIL_CDMA_InformationRecords *));
2963        return RIL_ERRNO_INVALID_RESPONSE;
2964    }
2965
2966    RIL_CDMA_InformationRecords *p_cur =
2967                             (RIL_CDMA_InformationRecords *) response;
2968    num = MIN(p_cur->numberOfInfoRecs, RIL_CDMA_MAX_NUMBER_OF_INFO_RECS);
2969
2970    startResponse;
2971    p.writeInt32(num);
2972
2973    for (int i = 0 ; i < num ; i++) {
2974        infoRec = &p_cur->infoRec[i];
2975        p.writeInt32(infoRec->name);
2976        switch (infoRec->name) {
2977            case RIL_CDMA_DISPLAY_INFO_REC:
2978            case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
2979                if (infoRec->rec.display.alpha_len >
2980                                         CDMA_ALPHA_INFO_BUFFER_LENGTH) {
2981                    RLOGE("invalid display info response length %d \
2982                          expected not more than %d\n",
2983                         (int)infoRec->rec.display.alpha_len,
2984                         CDMA_ALPHA_INFO_BUFFER_LENGTH);
2985                    return RIL_ERRNO_INVALID_RESPONSE;
2986                }
2987                string8 = (char*) calloc(infoRec->rec.display.alpha_len + 1, sizeof(char));
2988                if (string8 == NULL) {
2989                    RLOGE("Memory allocation failed for responseCdmaInformationRecords");
2990                    closeRequest;
2991                    return RIL_ERRNO_NO_MEMORY;
2992                }
2993                for (int i = 0 ; i < infoRec->rec.display.alpha_len ; i++) {
2994                    string8[i] = infoRec->rec.display.alpha_buf[i];
2995                }
2996                string8[(int)infoRec->rec.display.alpha_len] = '\0';
2997                writeStringToParcel(p, (const char*)string8);
2998                free(string8);
2999                string8 = NULL;
3000                break;
3001            case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
3002            case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
3003            case RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
3004                if (infoRec->rec.number.len > CDMA_NUMBER_INFO_BUFFER_LENGTH) {
3005                    RLOGE("invalid display info response length %d \
3006                          expected not more than %d\n",
3007                         (int)infoRec->rec.number.len,
3008                         CDMA_NUMBER_INFO_BUFFER_LENGTH);
3009                    return RIL_ERRNO_INVALID_RESPONSE;
3010                }
3011                string8 = (char*) calloc(infoRec->rec.number.len + 1, sizeof(char));
3012                if (string8 == NULL) {
3013                    RLOGE("Memory allocation failed for responseCdmaInformationRecords");
3014                    closeRequest;
3015                    return RIL_ERRNO_NO_MEMORY;
3016                }
3017                for (int i = 0 ; i < infoRec->rec.number.len; i++) {
3018                    string8[i] = infoRec->rec.number.buf[i];
3019                }
3020                string8[(int)infoRec->rec.number.len] = '\0';
3021                writeStringToParcel(p, (const char*)string8);
3022                free(string8);
3023                string8 = NULL;
3024                p.writeInt32(infoRec->rec.number.number_type);
3025                p.writeInt32(infoRec->rec.number.number_plan);
3026                p.writeInt32(infoRec->rec.number.pi);
3027                p.writeInt32(infoRec->rec.number.si);
3028                break;
3029            case RIL_CDMA_SIGNAL_INFO_REC:
3030                p.writeInt32(infoRec->rec.signal.isPresent);
3031                p.writeInt32(infoRec->rec.signal.signalType);
3032                p.writeInt32(infoRec->rec.signal.alertPitch);
3033                p.writeInt32(infoRec->rec.signal.signal);
3034
3035                appendPrintBuf("%sisPresent=%X, signalType=%X, \
3036                                alertPitch=%X, signal=%X, ",
3037                   printBuf, (int)infoRec->rec.signal.isPresent,
3038                   (int)infoRec->rec.signal.signalType,
3039                   (int)infoRec->rec.signal.alertPitch,
3040                   (int)infoRec->rec.signal.signal);
3041                removeLastChar;
3042                break;
3043            case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
3044                if (infoRec->rec.redir.redirectingNumber.len >
3045                                              CDMA_NUMBER_INFO_BUFFER_LENGTH) {
3046                    RLOGE("invalid display info response length %d \
3047                          expected not more than %d\n",
3048                         (int)infoRec->rec.redir.redirectingNumber.len,
3049                         CDMA_NUMBER_INFO_BUFFER_LENGTH);
3050                    return RIL_ERRNO_INVALID_RESPONSE;
3051                }
3052                string8 = (char*) calloc(infoRec->rec.redir.redirectingNumber.len + 1,
3053                        sizeof(char));
3054                if (string8 == NULL) {
3055                    RLOGE("Memory allocation failed for responseCdmaInformationRecords");
3056                    closeRequest;
3057                    return RIL_ERRNO_NO_MEMORY;
3058                }
3059                for (int i = 0;
3060                         i < infoRec->rec.redir.redirectingNumber.len;
3061                         i++) {
3062                    string8[i] = infoRec->rec.redir.redirectingNumber.buf[i];
3063                }
3064                string8[(int)infoRec->rec.redir.redirectingNumber.len] = '\0';
3065                writeStringToParcel(p, (const char*)string8);
3066                free(string8);
3067                string8 = NULL;
3068                p.writeInt32(infoRec->rec.redir.redirectingNumber.number_type);
3069                p.writeInt32(infoRec->rec.redir.redirectingNumber.number_plan);
3070                p.writeInt32(infoRec->rec.redir.redirectingNumber.pi);
3071                p.writeInt32(infoRec->rec.redir.redirectingNumber.si);
3072                p.writeInt32(infoRec->rec.redir.redirectingReason);
3073                break;
3074            case RIL_CDMA_LINE_CONTROL_INFO_REC:
3075                p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPolarityIncluded);
3076                p.writeInt32(infoRec->rec.lineCtrl.lineCtrlToggle);
3077                p.writeInt32(infoRec->rec.lineCtrl.lineCtrlReverse);
3078                p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPowerDenial);
3079
3080                appendPrintBuf("%slineCtrlPolarityIncluded=%d, \
3081                                lineCtrlToggle=%d, lineCtrlReverse=%d, \
3082                                lineCtrlPowerDenial=%d, ", printBuf,
3083                       (int)infoRec->rec.lineCtrl.lineCtrlPolarityIncluded,
3084                       (int)infoRec->rec.lineCtrl.lineCtrlToggle,
3085                       (int)infoRec->rec.lineCtrl.lineCtrlReverse,
3086                       (int)infoRec->rec.lineCtrl.lineCtrlPowerDenial);
3087                removeLastChar;
3088                break;
3089            case RIL_CDMA_T53_CLIR_INFO_REC:
3090                p.writeInt32((int)(infoRec->rec.clir.cause));
3091
3092                appendPrintBuf("%scause%d", printBuf, infoRec->rec.clir.cause);
3093                removeLastChar;
3094                break;
3095            case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
3096                p.writeInt32(infoRec->rec.audioCtrl.upLink);
3097                p.writeInt32(infoRec->rec.audioCtrl.downLink);
3098
3099                appendPrintBuf("%supLink=%d, downLink=%d, ", printBuf,
3100                        infoRec->rec.audioCtrl.upLink,
3101                        infoRec->rec.audioCtrl.downLink);
3102                removeLastChar;
3103                break;
3104            case RIL_CDMA_T53_RELEASE_INFO_REC:
3105                // TODO(Moto): See David Krause, he has the answer:)
3106                RLOGE("RIL_CDMA_T53_RELEASE_INFO_REC: return INVALID_RESPONSE");
3107                return RIL_ERRNO_INVALID_RESPONSE;
3108            default:
3109                RLOGE("Incorrect name value");
3110                return RIL_ERRNO_INVALID_RESPONSE;
3111        }
3112    }
3113    closeResponse;
3114
3115    return 0;
3116}
3117
3118static void responseRilSignalStrengthV5(Parcel &p, RIL_SignalStrength_v10 *p_cur) {
3119    p.writeInt32(p_cur->GW_SignalStrength.signalStrength);
3120    p.writeInt32(p_cur->GW_SignalStrength.bitErrorRate);
3121    p.writeInt32(p_cur->CDMA_SignalStrength.dbm);
3122    p.writeInt32(p_cur->CDMA_SignalStrength.ecio);
3123    p.writeInt32(p_cur->EVDO_SignalStrength.dbm);
3124    p.writeInt32(p_cur->EVDO_SignalStrength.ecio);
3125    p.writeInt32(p_cur->EVDO_SignalStrength.signalNoiseRatio);
3126}
3127
3128static void responseRilSignalStrengthV6Extra(Parcel &p, RIL_SignalStrength_v10 *p_cur) {
3129    /*
3130     * Fixup LTE for backwards compatibility
3131     */
3132    // signalStrength: -1 -> 99
3133    if (p_cur->LTE_SignalStrength.signalStrength == -1) {
3134        p_cur->LTE_SignalStrength.signalStrength = 99;
3135    }
3136    // rsrp: -1 -> INT_MAX all other negative value to positive.
3137    // So remap here
3138    if (p_cur->LTE_SignalStrength.rsrp == -1) {
3139        p_cur->LTE_SignalStrength.rsrp = INT_MAX;
3140    } else if (p_cur->LTE_SignalStrength.rsrp < -1) {
3141        p_cur->LTE_SignalStrength.rsrp = -p_cur->LTE_SignalStrength.rsrp;
3142    }
3143    // rsrq: -1 -> INT_MAX
3144    if (p_cur->LTE_SignalStrength.rsrq == -1) {
3145        p_cur->LTE_SignalStrength.rsrq = INT_MAX;
3146    }
3147    // Not remapping rssnr is already using INT_MAX
3148
3149    // cqi: -1 -> INT_MAX
3150    if (p_cur->LTE_SignalStrength.cqi == -1) {
3151        p_cur->LTE_SignalStrength.cqi = INT_MAX;
3152    }
3153
3154    p.writeInt32(p_cur->LTE_SignalStrength.signalStrength);
3155    p.writeInt32(p_cur->LTE_SignalStrength.rsrp);
3156    p.writeInt32(p_cur->LTE_SignalStrength.rsrq);
3157    p.writeInt32(p_cur->LTE_SignalStrength.rssnr);
3158    p.writeInt32(p_cur->LTE_SignalStrength.cqi);
3159}
3160
3161static void responseRilSignalStrengthV10(Parcel &p, RIL_SignalStrength_v10 *p_cur) {
3162    responseRilSignalStrengthV5(p, p_cur);
3163    responseRilSignalStrengthV6Extra(p, p_cur);
3164    p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp);
3165}
3166
3167static int responseRilSignalStrength(Parcel &p,
3168                    void *response, size_t responselen) {
3169    if (response == NULL && responselen != 0) {
3170        RLOGE("invalid response: NULL");
3171        return RIL_ERRNO_INVALID_RESPONSE;
3172    }
3173
3174    RIL_SignalStrength_v10 *p_cur;
3175    if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
3176        if (responselen >= sizeof (RIL_SignalStrength_v5)) {
3177            p_cur = ((RIL_SignalStrength_v10 *) response);
3178
3179            responseRilSignalStrengthV5(p, p_cur);
3180
3181            if (responselen >= sizeof (RIL_SignalStrength_v6)) {
3182                responseRilSignalStrengthV6Extra(p, p_cur);
3183                if (responselen >= sizeof (RIL_SignalStrength_v10)) {
3184                    p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp);
3185                } else {
3186                    p.writeInt32(INT_MAX);
3187                }
3188            } else {
3189                p.writeInt32(99);
3190                p.writeInt32(INT_MAX);
3191                p.writeInt32(INT_MAX);
3192                p.writeInt32(INT_MAX);
3193                p.writeInt32(INT_MAX);
3194                p.writeInt32(INT_MAX);
3195            }
3196        } else {
3197            RLOGE("invalid response length");
3198            return RIL_ERRNO_INVALID_RESPONSE;
3199        }
3200    } else { // RIL version >= 13
3201        if (responselen % sizeof(RIL_SignalStrength_v10) != 0) {
3202            RLOGE("Data structure expected is RIL_SignalStrength_v10");
3203            if (!isDebuggable()) {
3204                return RIL_ERRNO_INVALID_RESPONSE;
3205            } else {
3206                assert(0);
3207            }
3208        }
3209        p_cur = ((RIL_SignalStrength_v10 *) response);
3210        responseRilSignalStrengthV10(p, p_cur);
3211    }
3212    startResponse;
3213    appendPrintBuf("%s[signalStrength=%d,bitErrorRate=%d,\
3214            CDMA_SS.dbm=%d,CDMA_SSecio=%d,\
3215            EVDO_SS.dbm=%d,EVDO_SS.ecio=%d,\
3216            EVDO_SS.signalNoiseRatio=%d,\
3217            LTE_SS.signalStrength=%d,LTE_SS.rsrp=%d,LTE_SS.rsrq=%d,\
3218            LTE_SS.rssnr=%d,LTE_SS.cqi=%d,TDSCDMA_SS.rscp=%d]",
3219            printBuf,
3220            p_cur->GW_SignalStrength.signalStrength,
3221            p_cur->GW_SignalStrength.bitErrorRate,
3222            p_cur->CDMA_SignalStrength.dbm,
3223            p_cur->CDMA_SignalStrength.ecio,
3224            p_cur->EVDO_SignalStrength.dbm,
3225            p_cur->EVDO_SignalStrength.ecio,
3226            p_cur->EVDO_SignalStrength.signalNoiseRatio,
3227            p_cur->LTE_SignalStrength.signalStrength,
3228            p_cur->LTE_SignalStrength.rsrp,
3229            p_cur->LTE_SignalStrength.rsrq,
3230            p_cur->LTE_SignalStrength.rssnr,
3231            p_cur->LTE_SignalStrength.cqi,
3232            p_cur->TD_SCDMA_SignalStrength.rscp);
3233    closeResponse;
3234    return 0;
3235}
3236
3237static int responseCallRing(Parcel &p, void *response, size_t responselen) {
3238    if ((response == NULL) || (responselen == 0)) {
3239        return responseVoid(p, response, responselen);
3240    } else {
3241        return responseCdmaSignalInfoRecord(p, response, responselen);
3242    }
3243}
3244
3245static int responseCdmaSignalInfoRecord(Parcel &p, void *response, size_t responselen) {
3246    if (response == NULL || responselen == 0) {
3247        RLOGE("invalid response: NULL");
3248        return RIL_ERRNO_INVALID_RESPONSE;
3249    }
3250
3251    if (responselen != sizeof (RIL_CDMA_SignalInfoRecord)) {
3252        RLOGE("invalid response length %d expected sizeof (RIL_CDMA_SignalInfoRecord) of %d\n",
3253            (int)responselen, (int)sizeof (RIL_CDMA_SignalInfoRecord));
3254        return RIL_ERRNO_INVALID_RESPONSE;
3255    }
3256
3257    startResponse;
3258
3259    RIL_CDMA_SignalInfoRecord *p_cur = ((RIL_CDMA_SignalInfoRecord *) response);
3260    marshallSignalInfoRecord(p, *p_cur);
3261
3262    appendPrintBuf("%s[isPresent=%d,signalType=%d,alertPitch=%d\
3263              signal=%d]",
3264              printBuf,
3265              p_cur->isPresent,
3266              p_cur->signalType,
3267              p_cur->alertPitch,
3268              p_cur->signal);
3269
3270    closeResponse;
3271    return 0;
3272}
3273
3274static int responseCdmaCallWaiting(Parcel &p, void *response,
3275            size_t responselen) {
3276    if (response == NULL && responselen != 0) {
3277        RLOGE("invalid response: NULL");
3278        return RIL_ERRNO_INVALID_RESPONSE;
3279    }
3280
3281    if (responselen < sizeof(RIL_CDMA_CallWaiting_v6)) {
3282        RLOGW("Upgrade to ril version %d\n", RIL_VERSION);
3283    }
3284
3285    RIL_CDMA_CallWaiting_v6 *p_cur = ((RIL_CDMA_CallWaiting_v6 *) response);
3286
3287    writeStringToParcel(p, p_cur->number);
3288    p.writeInt32(p_cur->numberPresentation);
3289    writeStringToParcel(p, p_cur->name);
3290    marshallSignalInfoRecord(p, p_cur->signalInfoRecord);
3291
3292    if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
3293        if (responselen >= sizeof(RIL_CDMA_CallWaiting_v6)) {
3294            p.writeInt32(p_cur->number_type);
3295            p.writeInt32(p_cur->number_plan);
3296        } else {
3297            p.writeInt32(0);
3298            p.writeInt32(0);
3299        }
3300    } else { // RIL version >= 13
3301        if (responselen % sizeof(RIL_CDMA_CallWaiting_v6) != 0) {
3302            RLOGE("Data structure expected is RIL_CDMA_CallWaiting_v6");
3303            if (!isDebuggable()) {
3304                return RIL_ERRNO_INVALID_RESPONSE;
3305            } else {
3306                assert(0);
3307            }
3308        }
3309        p.writeInt32(p_cur->number_type);
3310        p.writeInt32(p_cur->number_plan);
3311    }
3312
3313    startResponse;
3314    appendPrintBuf("%snumber=%s,numberPresentation=%d, name=%s,\
3315            signalInfoRecord[isPresent=%d,signalType=%d,alertPitch=%d\
3316            signal=%d,number_type=%d,number_plan=%d]",
3317            printBuf,
3318            p_cur->number,
3319            p_cur->numberPresentation,
3320            p_cur->name,
3321            p_cur->signalInfoRecord.isPresent,
3322            p_cur->signalInfoRecord.signalType,
3323            p_cur->signalInfoRecord.alertPitch,
3324            p_cur->signalInfoRecord.signal,
3325            p_cur->number_type,
3326            p_cur->number_plan);
3327    closeResponse;
3328
3329    return 0;
3330}
3331
3332static void responseSimRefreshV7(Parcel &p, void *response) {
3333      RIL_SimRefreshResponse_v7 *p_cur = ((RIL_SimRefreshResponse_v7 *) response);
3334      p.writeInt32(p_cur->result);
3335      p.writeInt32(p_cur->ef_id);
3336      writeStringToParcel(p, p_cur->aid);
3337
3338      appendPrintBuf("%sresult=%d, ef_id=%d, aid=%s",
3339            printBuf,
3340            p_cur->result,
3341            p_cur->ef_id,
3342            p_cur->aid);
3343
3344}
3345
3346static int responseSimRefresh(Parcel &p, void *response, size_t responselen) {
3347    if (response == NULL && responselen != 0) {
3348        RLOGE("responseSimRefresh: invalid response: NULL");
3349        return RIL_ERRNO_INVALID_RESPONSE;
3350    }
3351
3352    startResponse;
3353    if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
3354        if (s_callbacks.version >= 7) {
3355            responseSimRefreshV7(p, response);
3356        } else {
3357            int *p_cur = ((int *) response);
3358            p.writeInt32(p_cur[0]);
3359            p.writeInt32(p_cur[1]);
3360            writeStringToParcel(p, NULL);
3361
3362            appendPrintBuf("%sresult=%d, ef_id=%d",
3363                    printBuf,
3364                    p_cur[0],
3365                    p_cur[1]);
3366        }
3367    } else { // RIL version >= 13
3368        if (responselen % sizeof(RIL_SimRefreshResponse_v7) != 0) {
3369            RLOGE("Data structure expected is RIL_SimRefreshResponse_v7");
3370            if (!isDebuggable()) {
3371                return RIL_ERRNO_INVALID_RESPONSE;
3372            } else {
3373                assert(0);
3374            }
3375        }
3376        responseSimRefreshV7(p, response);
3377
3378    }
3379    closeResponse;
3380
3381    return 0;
3382}
3383
3384static int responseCellInfoListV6(Parcel &p, void *response, size_t responselen) {
3385    if (response == NULL && responselen != 0) {
3386        RLOGE("invalid response: NULL");
3387        return RIL_ERRNO_INVALID_RESPONSE;
3388    }
3389
3390    if (responselen % sizeof(RIL_CellInfo) != 0) {
3391        RLOGE("responseCellInfoList: invalid response length %d expected multiple of %d",
3392                (int)responselen, (int)sizeof(RIL_CellInfo));
3393        return RIL_ERRNO_INVALID_RESPONSE;
3394    }
3395
3396    int num = responselen / sizeof(RIL_CellInfo);
3397    p.writeInt32(num);
3398
3399    RIL_CellInfo *p_cur = (RIL_CellInfo *) response;
3400    startResponse;
3401    int i;
3402    for (i = 0; i < num; i++) {
3403        p.writeInt32((int)p_cur->cellInfoType);
3404        p.writeInt32(p_cur->registered);
3405        p.writeInt32(p_cur->timeStampType);
3406        p.writeInt64(p_cur->timeStamp);
3407        switch(p_cur->cellInfoType) {
3408            case RIL_CELL_INFO_TYPE_GSM: {
3409                p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mcc);
3410                p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mnc);
3411                p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.lac);
3412                p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.cid);
3413                p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength);
3414                p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
3415                break;
3416            }
3417            case RIL_CELL_INFO_TYPE_WCDMA: {
3418                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc);
3419                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc);
3420                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.lac);
3421                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.cid);
3422                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
3423                p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength);
3424                p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
3425                break;
3426            }
3427            case RIL_CELL_INFO_TYPE_CDMA: {
3428                p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.networkId);
3429                p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.systemId);
3430                p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.basestationId);
3431                p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.longitude);
3432                p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
3433
3434                p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.dbm);
3435                p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.ecio);
3436                p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.dbm);
3437                p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.ecio);
3438                p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
3439                break;
3440            }
3441            case RIL_CELL_INFO_TYPE_LTE: {
3442                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mcc);
3443                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mnc);
3444                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.ci);
3445                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.pci);
3446                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.tac);
3447
3448                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.signalStrength);
3449                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrp);
3450                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrq);
3451                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rssnr);
3452                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.cqi);
3453                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
3454                break;
3455            }
3456            case RIL_CELL_INFO_TYPE_TD_SCDMA: {
3457                p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc);
3458                p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc);
3459                p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac);
3460                p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid);
3461                p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid);
3462                p.writeInt32(p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp);
3463                break;
3464            }
3465        }
3466        p_cur += 1;
3467    }
3468    removeLastChar;
3469    closeResponse;
3470
3471    return 0;
3472}
3473
3474static int responseCellInfoListV12(Parcel &p, void *response, size_t responselen) {
3475    if (response == NULL && responselen != 0) {
3476        RLOGE("invalid response: NULL");
3477        return RIL_ERRNO_INVALID_RESPONSE;
3478    }
3479
3480    if (responselen % sizeof(RIL_CellInfo_v12) != 0) {
3481        RLOGE("responseCellInfoList: invalid response length %d expected multiple of %d",
3482                (int)responselen, (int)sizeof(RIL_CellInfo_v12));
3483        return RIL_ERRNO_INVALID_RESPONSE;
3484    }
3485
3486    int num = responselen / sizeof(RIL_CellInfo_v12);
3487    p.writeInt32(num);
3488
3489    RIL_CellInfo_v12 *p_cur = (RIL_CellInfo_v12 *) response;
3490    startResponse;
3491    int i;
3492    for (i = 0; i < num; i++) {
3493        p.writeInt32((int)p_cur->cellInfoType);
3494        p.writeInt32(p_cur->registered);
3495        p.writeInt32(p_cur->timeStampType);
3496        p.writeInt64(p_cur->timeStamp);
3497        switch(p_cur->cellInfoType) {
3498            case RIL_CELL_INFO_TYPE_GSM: {
3499                p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mcc);
3500                p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mnc);
3501                p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.lac);
3502                p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.cid);
3503                p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.arfcn);
3504                p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.bsic);
3505                p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength);
3506                p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
3507                p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.timingAdvance);
3508                break;
3509            }
3510            case RIL_CELL_INFO_TYPE_WCDMA: {
3511                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc);
3512                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc);
3513                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.lac);
3514                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.cid);
3515                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
3516                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.uarfcn);
3517                p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength);
3518                p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
3519                break;
3520            }
3521            case RIL_CELL_INFO_TYPE_CDMA: {
3522                p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.networkId);
3523                p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.systemId);
3524                p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.basestationId);
3525                p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.longitude);
3526                p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
3527
3528                p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.dbm);
3529                p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.ecio);
3530                p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.dbm);
3531                p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.ecio);
3532                p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
3533                break;
3534            }
3535            case RIL_CELL_INFO_TYPE_LTE: {
3536                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mcc);
3537                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mnc);
3538                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.ci);
3539                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.pci);
3540                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.tac);
3541                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.earfcn);
3542
3543                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.signalStrength);
3544                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrp);
3545                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrq);
3546                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rssnr);
3547                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.cqi);
3548                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
3549                break;
3550            }
3551            case RIL_CELL_INFO_TYPE_TD_SCDMA: {
3552                p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc);
3553                p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc);
3554                p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac);
3555                p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid);
3556                p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid);
3557                p.writeInt32(p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp);
3558                break;
3559            }
3560        }
3561        p_cur += 1;
3562    }
3563    removeLastChar;
3564    closeResponse;
3565    return 0;
3566}
3567
3568static int responseCellInfoList(Parcel &p, void *response, size_t responselen)
3569{
3570    if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
3571        if (s_callbacks.version < 12) {
3572            RLOGD("responseCellInfoList: v6");
3573            return responseCellInfoListV6(p, response, responselen);
3574        } else {
3575            RLOGD("responseCellInfoList: v12");
3576            return responseCellInfoListV12(p, response, responselen);
3577        }
3578    } else { // RIL version >= 13
3579        if (responselen % sizeof(RIL_CellInfo_v12) != 0) {
3580            RLOGE("Data structure expected is RIL_CellInfo_v12");
3581            if (!isDebuggable()) {
3582                return RIL_ERRNO_INVALID_RESPONSE;
3583            } else {
3584                assert(0);
3585            }
3586        }
3587        return responseCellInfoListV12(p, response, responselen);
3588    }
3589
3590    return 0;
3591}
3592
3593static int responseHardwareConfig(Parcel &p, void *response, size_t responselen)
3594{
3595   if (response == NULL && responselen != 0) {
3596       RLOGE("invalid response: NULL");
3597       return RIL_ERRNO_INVALID_RESPONSE;
3598   }
3599
3600   if (responselen % sizeof(RIL_HardwareConfig) != 0) {
3601       RLOGE("responseHardwareConfig: invalid response length %d expected multiple of %d",
3602          (int)responselen, (int)sizeof(RIL_HardwareConfig));
3603       return RIL_ERRNO_INVALID_RESPONSE;
3604   }
3605
3606   int num = responselen / sizeof(RIL_HardwareConfig);
3607   int i;
3608   RIL_HardwareConfig *p_cur = (RIL_HardwareConfig *) response;
3609
3610   p.writeInt32(num);
3611
3612   startResponse;
3613   for (i = 0; i < num; i++) {
3614      switch (p_cur[i].type) {
3615         case RIL_HARDWARE_CONFIG_MODEM: {
3616            writeStringToParcel(p, p_cur[i].uuid);
3617            p.writeInt32((int)p_cur[i].state);
3618            p.writeInt32(p_cur[i].cfg.modem.rat);
3619            p.writeInt32(p_cur[i].cfg.modem.maxVoice);
3620            p.writeInt32(p_cur[i].cfg.modem.maxData);
3621            p.writeInt32(p_cur[i].cfg.modem.maxStandby);
3622
3623            appendPrintBuf("%s modem: uuid=%s,state=%d,rat=%08x,maxV=%d,maxD=%d,maxS=%d", printBuf,
3624               p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.modem.rat,
3625               p_cur[i].cfg.modem.maxVoice, p_cur[i].cfg.modem.maxData, p_cur[i].cfg.modem.maxStandby);
3626            break;
3627         }
3628         case RIL_HARDWARE_CONFIG_SIM: {
3629            writeStringToParcel(p, p_cur[i].uuid);
3630            p.writeInt32((int)p_cur[i].state);
3631            writeStringToParcel(p, p_cur[i].cfg.sim.modemUuid);
3632
3633            appendPrintBuf("%s sim: uuid=%s,state=%d,modem-uuid=%s", printBuf,
3634               p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.sim.modemUuid);
3635            break;
3636         }
3637      }
3638   }
3639   removeLastChar;
3640   closeResponse;
3641   return 0;
3642}
3643
3644static int responseRadioCapability(Parcel &p, void *response, size_t responselen) {
3645    if (response == NULL) {
3646        RLOGE("invalid response: NULL");
3647        return RIL_ERRNO_INVALID_RESPONSE;
3648    }
3649
3650    if (responselen != sizeof (RIL_RadioCapability) ) {
3651        RLOGE("invalid response length was %d expected %d",
3652                (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
3653        return RIL_ERRNO_INVALID_RESPONSE;
3654    }
3655
3656    RIL_RadioCapability *p_cur = (RIL_RadioCapability *) response;
3657    p.writeInt32(p_cur->version);
3658    p.writeInt32(p_cur->session);
3659    p.writeInt32(p_cur->phase);
3660    p.writeInt32(p_cur->rat);
3661    writeStringToParcel(p, p_cur->logicalModemUuid);
3662    p.writeInt32(p_cur->status);
3663
3664    startResponse;
3665    appendPrintBuf("%s[version=%d,session=%d,phase=%d,\
3666            rat=%s,logicalModemUuid=%s,status=%d]",
3667            printBuf,
3668            p_cur->version,
3669            p_cur->session,
3670            p_cur->phase,
3671            p_cur->rat,
3672            p_cur->logicalModemUuid,
3673            p_cur->status);
3674    closeResponse;
3675    return 0;
3676}
3677
3678static int responseSSData(Parcel &p, void *response, size_t responselen) {
3679    RLOGD("In responseSSData");
3680    int num;
3681
3682    if (response == NULL && responselen != 0) {
3683        RLOGE("invalid response length was %d expected %d",
3684                (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
3685        return RIL_ERRNO_INVALID_RESPONSE;
3686    }
3687
3688    if (responselen != sizeof(RIL_StkCcUnsolSsResponse)) {
3689        RLOGE("invalid response length %d, expected %d",
3690               (int)responselen, (int)sizeof(RIL_StkCcUnsolSsResponse));
3691        return RIL_ERRNO_INVALID_RESPONSE;
3692    }
3693
3694    startResponse;
3695    RIL_StkCcUnsolSsResponse *p_cur = (RIL_StkCcUnsolSsResponse *) response;
3696    p.writeInt32(p_cur->serviceType);
3697    p.writeInt32(p_cur->requestType);
3698    p.writeInt32(p_cur->teleserviceType);
3699    p.writeInt32(p_cur->serviceClass);
3700    p.writeInt32(p_cur->result);
3701
3702    if (isServiceTypeCfQuery(p_cur->serviceType, p_cur->requestType)) {
3703        RLOGD("responseSSData CF type, num of Cf elements %d", p_cur->cfData.numValidIndexes);
3704        if (p_cur->cfData.numValidIndexes > NUM_SERVICE_CLASSES) {
3705            RLOGE("numValidIndexes is greater than max value %d, "
3706                  "truncating it to max value", NUM_SERVICE_CLASSES);
3707            p_cur->cfData.numValidIndexes = NUM_SERVICE_CLASSES;
3708        }
3709        /* number of call info's */
3710        p.writeInt32(p_cur->cfData.numValidIndexes);
3711
3712        for (int i = 0; i < p_cur->cfData.numValidIndexes; i++) {
3713             RIL_CallForwardInfo cf = p_cur->cfData.cfInfo[i];
3714
3715             p.writeInt32(cf.status);
3716             p.writeInt32(cf.reason);
3717             p.writeInt32(cf.serviceClass);
3718             p.writeInt32(cf.toa);
3719             writeStringToParcel(p, cf.number);
3720             p.writeInt32(cf.timeSeconds);
3721             appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
3722                 (cf.status==1)?"enable":"disable", cf.reason, cf.serviceClass, cf.toa,
3723                  (char*)cf.number, cf.timeSeconds);
3724             RLOGD("Data: %d,reason=%d,cls=%d,toa=%d,num=%s,tout=%d],", cf.status,
3725                  cf.reason, cf.serviceClass, cf.toa, (char*)cf.number, cf.timeSeconds);
3726        }
3727    } else {
3728        p.writeInt32 (SS_INFO_MAX);
3729
3730        /* each int*/
3731        for (int i = 0; i < SS_INFO_MAX; i++) {
3732             appendPrintBuf("%s%d,", printBuf, p_cur->ssInfo[i]);
3733             RLOGD("Data: %d",p_cur->ssInfo[i]);
3734             p.writeInt32(p_cur->ssInfo[i]);
3735        }
3736    }
3737    removeLastChar;
3738    closeResponse;
3739
3740    return 0;
3741}
3742
3743static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType) {
3744    if ((reqType == SS_INTERROGATION) &&
3745        (serType == SS_CFU ||
3746         serType == SS_CF_BUSY ||
3747         serType == SS_CF_NO_REPLY ||
3748         serType == SS_CF_NOT_REACHABLE ||
3749         serType == SS_CF_ALL ||
3750         serType == SS_CF_ALL_CONDITIONAL)) {
3751        return true;
3752    }
3753    return false;
3754}
3755
3756static void triggerEvLoop() {
3757    int ret;
3758    if (!pthread_equal(pthread_self(), s_tid_dispatch)) {
3759        /* trigger event loop to wakeup. No reason to do this,
3760         * if we're in the event loop thread */
3761         do {
3762            ret = write (s_fdWakeupWrite, " ", 1);
3763         } while (ret < 0 && errno == EINTR);
3764    }
3765}
3766
3767static void rilEventAddWakeup(struct ril_event *ev) {
3768    ril_event_add(ev);
3769    triggerEvLoop();
3770}
3771
3772static void sendSimStatusAppInfo(Parcel &p, int num_apps, RIL_AppStatus appStatus[]) {
3773        p.writeInt32(num_apps);
3774        startResponse;
3775        for (int i = 0; i < num_apps; i++) {
3776            p.writeInt32(appStatus[i].app_type);
3777            p.writeInt32(appStatus[i].app_state);
3778            p.writeInt32(appStatus[i].perso_substate);
3779            writeStringToParcel(p, (const char*)(appStatus[i].aid_ptr));
3780            writeStringToParcel(p, (const char*)
3781                                          (appStatus[i].app_label_ptr));
3782            p.writeInt32(appStatus[i].pin1_replaced);
3783            p.writeInt32(appStatus[i].pin1);
3784            p.writeInt32(appStatus[i].pin2);
3785            appendPrintBuf("%s[app_type=%d,app_state=%d,perso_substate=%d,\
3786                    aid_ptr=%s,app_label_ptr=%s,pin1_replaced=%d,pin1=%d,pin2=%d],",
3787                    printBuf,
3788                    appStatus[i].app_type,
3789                    appStatus[i].app_state,
3790                    appStatus[i].perso_substate,
3791                    appStatus[i].aid_ptr,
3792                    appStatus[i].app_label_ptr,
3793                    appStatus[i].pin1_replaced,
3794                    appStatus[i].pin1,
3795                    appStatus[i].pin2);
3796        }
3797        closeResponse;
3798}
3799
3800static void responseSimStatusV5(Parcel &p, void *response) {
3801    RIL_CardStatus_v5 *p_cur = ((RIL_CardStatus_v5 *) response);
3802
3803    p.writeInt32(p_cur->card_state);
3804    p.writeInt32(p_cur->universal_pin_state);
3805    p.writeInt32(p_cur->gsm_umts_subscription_app_index);
3806    p.writeInt32(p_cur->cdma_subscription_app_index);
3807
3808    sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
3809}
3810
3811static void responseSimStatusV6(Parcel &p, void *response) {
3812    RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
3813
3814    p.writeInt32(p_cur->card_state);
3815    p.writeInt32(p_cur->universal_pin_state);
3816    p.writeInt32(p_cur->gsm_umts_subscription_app_index);
3817    p.writeInt32(p_cur->cdma_subscription_app_index);
3818    p.writeInt32(p_cur->ims_subscription_app_index);
3819
3820    sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
3821}
3822
3823static int responseSimStatus(Parcel &p, void *response, size_t responselen) {
3824    int i;
3825
3826    if (response == NULL && responselen != 0) {
3827        RLOGE("invalid response: NULL");
3828        return RIL_ERRNO_INVALID_RESPONSE;
3829    }
3830
3831    if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
3832        if (responselen == sizeof (RIL_CardStatus_v6)) {
3833            responseSimStatusV6(p, response);
3834        } else if (responselen == sizeof (RIL_CardStatus_v5)) {
3835            responseSimStatusV5(p, response);
3836        } else {
3837            RLOGE("responseSimStatus: A RilCardStatus_v6 or _v5 expected\n");
3838            return RIL_ERRNO_INVALID_RESPONSE;
3839        }
3840    } else { // RIL version >= 13
3841        if (responselen % sizeof(RIL_CardStatus_v6) != 0) {
3842            RLOGE("Data structure expected is RIL_CardStatus_v6");
3843            if (!isDebuggable()) {
3844                return RIL_ERRNO_INVALID_RESPONSE;
3845            } else {
3846                assert(0);
3847            }
3848        }
3849        responseSimStatusV6(p, response);
3850    }
3851
3852    return 0;
3853}
3854
3855static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen) {
3856    int num = responselen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *);
3857    p.writeInt32(num);
3858
3859    startResponse;
3860    RIL_GSM_BroadcastSmsConfigInfo **p_cur =
3861                (RIL_GSM_BroadcastSmsConfigInfo **) response;
3862    for (int i = 0; i < num; i++) {
3863        p.writeInt32(p_cur[i]->fromServiceId);
3864        p.writeInt32(p_cur[i]->toServiceId);
3865        p.writeInt32(p_cur[i]->fromCodeScheme);
3866        p.writeInt32(p_cur[i]->toCodeScheme);
3867        p.writeInt32(p_cur[i]->selected);
3868
3869        appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId=%d, \
3870                fromCodeScheme=%d, toCodeScheme=%d, selected =%d]",
3871                printBuf, i, p_cur[i]->fromServiceId, p_cur[i]->toServiceId,
3872                p_cur[i]->fromCodeScheme, p_cur[i]->toCodeScheme,
3873                p_cur[i]->selected);
3874    }
3875    closeResponse;
3876
3877    return 0;
3878}
3879
3880static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen) {
3881    RIL_CDMA_BroadcastSmsConfigInfo **p_cur =
3882               (RIL_CDMA_BroadcastSmsConfigInfo **) response;
3883
3884    int num = responselen / sizeof (RIL_CDMA_BroadcastSmsConfigInfo *);
3885    p.writeInt32(num);
3886
3887    startResponse;
3888    for (int i = 0 ; i < num ; i++ ) {
3889        p.writeInt32(p_cur[i]->service_category);
3890        p.writeInt32(p_cur[i]->language);
3891        p.writeInt32(p_cur[i]->selected);
3892
3893        appendPrintBuf("%s [%d: srvice_category=%d, language =%d, \
3894              selected =%d], ",
3895              printBuf, i, p_cur[i]->service_category, p_cur[i]->language,
3896              p_cur[i]->selected);
3897    }
3898    closeResponse;
3899
3900    return 0;
3901}
3902
3903static int responseCdmaSms(Parcel &p, void *response, size_t responselen) {
3904    int num;
3905    int digitCount;
3906    int digitLimit;
3907    uint8_t uct;
3908    void* dest;
3909
3910    RLOGD("Inside responseCdmaSms");
3911
3912    if (response == NULL && responselen != 0) {
3913        RLOGE("invalid response: NULL");
3914        return RIL_ERRNO_INVALID_RESPONSE;
3915    }
3916
3917    if (responselen != sizeof(RIL_CDMA_SMS_Message)) {
3918        RLOGE("invalid response length was %d expected %d",
3919                (int)responselen, (int)sizeof(RIL_CDMA_SMS_Message));
3920        return RIL_ERRNO_INVALID_RESPONSE;
3921    }
3922
3923    RIL_CDMA_SMS_Message *p_cur = (RIL_CDMA_SMS_Message *) response;
3924    p.writeInt32(p_cur->uTeleserviceID);
3925    p.write(&(p_cur->bIsServicePresent),sizeof(uct));
3926    p.writeInt32(p_cur->uServicecategory);
3927    p.writeInt32(p_cur->sAddress.digit_mode);
3928    p.writeInt32(p_cur->sAddress.number_mode);
3929    p.writeInt32(p_cur->sAddress.number_type);
3930    p.writeInt32(p_cur->sAddress.number_plan);
3931    p.write(&(p_cur->sAddress.number_of_digits), sizeof(uct));
3932    digitLimit= MIN((p_cur->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
3933    for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
3934        p.write(&(p_cur->sAddress.digits[digitCount]),sizeof(uct));
3935    }
3936
3937    p.writeInt32(p_cur->sSubAddress.subaddressType);
3938    p.write(&(p_cur->sSubAddress.odd),sizeof(uct));
3939    p.write(&(p_cur->sSubAddress.number_of_digits),sizeof(uct));
3940    digitLimit= MIN((p_cur->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
3941    for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
3942        p.write(&(p_cur->sSubAddress.digits[digitCount]),sizeof(uct));
3943    }
3944
3945    digitLimit= MIN((p_cur->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
3946    p.writeInt32(p_cur->uBearerDataLen);
3947    for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
3948       p.write(&(p_cur->aBearerData[digitCount]), sizeof(uct));
3949    }
3950
3951    startResponse;
3952    appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
3953            sAddress.digit_mode=%d, sAddress.number_mode=%d, sAddress.number_type=%d, ",
3954            printBuf, p_cur->uTeleserviceID,p_cur->bIsServicePresent,p_cur->uServicecategory,
3955            p_cur->sAddress.digit_mode, p_cur->sAddress.number_mode,p_cur->sAddress.number_type);
3956    closeResponse;
3957
3958    return 0;
3959}
3960
3961static int responseDcRtInfo(Parcel &p, void *response, size_t responselen)
3962{
3963    int num = responselen / sizeof(RIL_DcRtInfo);
3964    if ((responselen % sizeof(RIL_DcRtInfo) != 0) || (num != 1)) {
3965        RLOGE("responseDcRtInfo: invalid response length %d expected multiple of %d",
3966                (int)responselen, (int)sizeof(RIL_DcRtInfo));
3967        return RIL_ERRNO_INVALID_RESPONSE;
3968    }
3969
3970    startResponse;
3971    RIL_DcRtInfo *pDcRtInfo = (RIL_DcRtInfo *)response;
3972    p.writeInt64(pDcRtInfo->time);
3973    p.writeInt32(pDcRtInfo->powerState);
3974    appendPrintBuf("%s[time=%d,powerState=%d]", printBuf,
3975        pDcRtInfo->time,
3976        pDcRtInfo->powerState);
3977    closeResponse;
3978
3979    return 0;
3980}
3981
3982static int responseLceStatus(Parcel &p, void *response, size_t responselen) {
3983  if (response == NULL || responselen != sizeof(RIL_LceStatusInfo)) {
3984    if (response == NULL) {
3985      RLOGE("invalid response: NULL");
3986    }
3987    else {
3988      RLOGE("responseLceStatus: invalid response length %u expecting len: %u",
3989            (unsigned)sizeof(RIL_LceStatusInfo), (unsigned)responselen);
3990    }
3991    return RIL_ERRNO_INVALID_RESPONSE;
3992  }
3993
3994  RIL_LceStatusInfo *p_cur = (RIL_LceStatusInfo *)response;
3995  p.write((void *)p_cur, 1);  // p_cur->lce_status takes one byte.
3996  p.writeInt32(p_cur->actual_interval_ms);
3997
3998  startResponse;
3999  appendPrintBuf("LCE Status: %d, actual_interval_ms: %d",
4000                 p_cur->lce_status, p_cur->actual_interval_ms);
4001  closeResponse;
4002
4003  return 0;
4004}
4005
4006static int responseLceData(Parcel &p, void *response, size_t responselen) {
4007  if (response == NULL || responselen != sizeof(RIL_LceDataInfo)) {
4008    if (response == NULL) {
4009      RLOGE("invalid response: NULL");
4010    }
4011    else {
4012      RLOGE("responseLceData: invalid response length %u expecting len: %u",
4013            (unsigned)sizeof(RIL_LceDataInfo), (unsigned)responselen);
4014    }
4015    return RIL_ERRNO_INVALID_RESPONSE;
4016  }
4017
4018  RIL_LceDataInfo *p_cur = (RIL_LceDataInfo *)response;
4019  p.writeInt32(p_cur->last_hop_capacity_kbps);
4020
4021  /* p_cur->confidence_level and p_cur->lce_suspended take 1 byte each.*/
4022  p.write((void *)&(p_cur->confidence_level), 1);
4023  p.write((void *)&(p_cur->lce_suspended), 1);
4024
4025  startResponse;
4026  appendPrintBuf("LCE info received: capacity %d confidence level %d \
4027                  and suspended %d",
4028                  p_cur->last_hop_capacity_kbps, p_cur->confidence_level,
4029                  p_cur->lce_suspended);
4030  closeResponse;
4031
4032  return 0;
4033}
4034
4035static int responseActivityData(Parcel &p, void *response, size_t responselen) {
4036  if (response == NULL || responselen != sizeof(RIL_ActivityStatsInfo)) {
4037    if (response == NULL) {
4038      RLOGE("invalid response: NULL");
4039    }
4040    else {
4041      RLOGE("responseActivityData: invalid response length %u expecting len: %u",
4042            (unsigned)sizeof(RIL_ActivityStatsInfo), (unsigned)responselen);
4043    }
4044    return RIL_ERRNO_INVALID_RESPONSE;
4045  }
4046
4047  RIL_ActivityStatsInfo *p_cur = (RIL_ActivityStatsInfo *)response;
4048  p.writeInt32(p_cur->sleep_mode_time_ms);
4049  p.writeInt32(p_cur->idle_mode_time_ms);
4050  for(int i = 0; i < RIL_NUM_TX_POWER_LEVELS; i++) {
4051    p.writeInt32(p_cur->tx_mode_time_ms[i]);
4052  }
4053  p.writeInt32(p_cur->rx_mode_time_ms);
4054
4055  startResponse;
4056  appendPrintBuf("Modem activity info received: sleep_mode_time_ms %d idle_mode_time_ms %d \
4057                  tx_mode_time_ms %d %d %d %d %d and rx_mode_time_ms %d",
4058                  p_cur->sleep_mode_time_ms, p_cur->idle_mode_time_ms, p_cur->tx_mode_time_ms[0],
4059                  p_cur->tx_mode_time_ms[1], p_cur->tx_mode_time_ms[2], p_cur->tx_mode_time_ms[3],
4060                  p_cur->tx_mode_time_ms[4], p_cur->rx_mode_time_ms);
4061   closeResponse;
4062
4063  return 0;
4064}
4065
4066static int responseCarrierRestrictions(Parcel &p, void *response, size_t responselen) {
4067  if (response == NULL) {
4068    RLOGE("invalid response: NULL");
4069    return RIL_ERRNO_INVALID_RESPONSE;
4070  }
4071  if (responselen != sizeof(RIL_CarrierRestrictions)) {
4072    RLOGE("responseCarrierRestrictions: invalid response length %u expecting len: %u",
4073          (unsigned)responselen, (unsigned)sizeof(RIL_CarrierRestrictions));
4074    return RIL_ERRNO_INVALID_RESPONSE;
4075  }
4076
4077  RIL_CarrierRestrictions *p_cr = (RIL_CarrierRestrictions *)response;
4078  startResponse;
4079
4080  p.writeInt32(p_cr->len_allowed_carriers);
4081  p.writeInt32(p_cr->len_excluded_carriers);
4082  appendPrintBuf(" %s len_allowed_carriers: %d, len_excluded_carriers: %d,", printBuf,
4083                 p_cr->len_allowed_carriers,p_cr->len_excluded_carriers);
4084
4085  appendPrintBuf(" %s allowed_carriers:", printBuf);
4086  for(int32_t i = 0; i < p_cr->len_allowed_carriers; i++) {
4087    RIL_Carrier *carrier = p_cr->allowed_carriers + i;
4088    writeStringToParcel(p, carrier->mcc);
4089    writeStringToParcel(p, carrier->mnc);
4090    p.writeInt32(carrier->match_type);
4091    writeStringToParcel(p, carrier->match_data);
4092    appendPrintBuf(" %s [%d mcc: %s, mnc: %s, match_type: %d, match_data: %s],", printBuf,
4093                   i, carrier->mcc, carrier->mnc, carrier->match_type, carrier->match_data);
4094  }
4095
4096  appendPrintBuf(" %s excluded_carriers:", printBuf);
4097  for(int32_t i = 0; i < p_cr->len_excluded_carriers; i++) {
4098    RIL_Carrier *carrier = p_cr->excluded_carriers + i;
4099    writeStringToParcel(p, carrier->mcc);
4100    writeStringToParcel(p, carrier->mnc);
4101    p.writeInt32(carrier->match_type);
4102    writeStringToParcel(p, carrier->match_data);
4103    appendPrintBuf(" %s [%d mcc: %s, mnc: %s, match_type: %d, match_data: %s],", printBuf,
4104                   i, carrier->mcc, carrier->mnc, carrier->match_type, carrier->match_data);
4105  }
4106
4107  closeResponse;
4108
4109  return 0;
4110}
4111
4112static int responsePcoData(Parcel &p, void *response, size_t responselen) {
4113  if (response == NULL) {
4114    RLOGE("responsePcoData: invalid NULL response");
4115    return RIL_ERRNO_INVALID_RESPONSE;
4116  }
4117  if (responselen != sizeof(RIL_PCO_Data)) {
4118    RLOGE("responsePcoData: invalid response length %u, expecting %u",
4119          (unsigned)responselen, (unsigned)sizeof(RIL_PCO_Data));
4120    return RIL_ERRNO_INVALID_RESPONSE;
4121  }
4122
4123  RIL_PCO_Data *p_cur = (RIL_PCO_Data *)response;
4124  p.writeInt32(p_cur->cid);
4125  writeStringToParcel(p, p_cur->bearer_proto);
4126  p.writeInt32(p_cur->pco_id);
4127  p.writeInt32(p_cur->contents_length);
4128  p.write(p_cur->contents, p_cur->contents_length);
4129
4130  startResponse;
4131      appendPrintBuf("PCO data received: cid %d, id %d, length %d",
4132                     p_cur->cid, p_cur->pco_id, p_cur->contents_length);
4133  closeResponse;
4134
4135  return 0;
4136}
4137
4138/**
4139 * A write on the wakeup fd is done just to pop us out of select()
4140 * We empty the buffer here and then ril_event will reset the timers on the
4141 * way back down
4142 */
4143static void processWakeupCallback(int fd, short flags, void *param) {
4144    char buff[16];
4145    int ret;
4146
4147    RLOGV("processWakeupCallback");
4148
4149    /* empty our wakeup socket out */
4150    do {
4151        ret = read(s_fdWakeupRead, &buff, sizeof(buff));
4152    } while (ret > 0 || (ret < 0 && errno == EINTR));
4153}
4154
4155static void onCommandsSocketClosed(RIL_SOCKET_ID socket_id) {
4156    int ret;
4157    RequestInfo *p_cur;
4158    /* Hook for current context
4159       pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
4160    pthread_mutex_t * pendingRequestsMutexHook = &s_pendingRequestsMutex;
4161    /* pendingRequestsHook refer to &s_pendingRequests */
4162    RequestInfo **    pendingRequestsHook = &s_pendingRequests;
4163
4164#if (SIM_COUNT >= 2)
4165    if (socket_id == RIL_SOCKET_2) {
4166        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
4167        pendingRequestsHook = &s_pendingRequests_socket2;
4168    }
4169#if (SIM_COUNT >= 3)
4170    else if (socket_id == RIL_SOCKET_3) {
4171        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
4172        pendingRequestsHook = &s_pendingRequests_socket3;
4173    }
4174#endif
4175#if (SIM_COUNT >= 4)
4176    else if (socket_id == RIL_SOCKET_4) {
4177        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
4178        pendingRequestsHook = &s_pendingRequests_socket4;
4179    }
4180#endif
4181#endif
4182    /* mark pending requests as "cancelled" so we dont report responses */
4183    ret = pthread_mutex_lock(pendingRequestsMutexHook);
4184    assert (ret == 0);
4185
4186    p_cur = *pendingRequestsHook;
4187
4188    for (p_cur = *pendingRequestsHook
4189            ; p_cur != NULL
4190            ; p_cur  = p_cur->p_next
4191    ) {
4192        p_cur->cancelled = 1;
4193    }
4194
4195    ret = pthread_mutex_unlock(pendingRequestsMutexHook);
4196    assert (ret == 0);
4197}
4198
4199static void processCommandsCallback(int fd, short flags, void *param) {
4200    RecordStream *p_rs;
4201    void *p_record;
4202    size_t recordlen;
4203    int ret;
4204    SocketListenParam *p_info = (SocketListenParam *)param;
4205
4206    assert(fd == p_info->fdCommand);
4207
4208    p_rs = p_info->p_rs;
4209
4210    for (;;) {
4211        /* loop until EAGAIN/EINTR, end of stream, or other error */
4212        ret = record_stream_get_next(p_rs, &p_record, &recordlen);
4213
4214        if (ret == 0 && p_record == NULL) {
4215            /* end-of-stream */
4216            break;
4217        } else if (ret < 0) {
4218            break;
4219        } else if (ret == 0) { /* && p_record != NULL */
4220            processCommandBuffer(p_record, recordlen, p_info->socket_id);
4221        }
4222    }
4223
4224    if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) {
4225        /* fatal error or end-of-stream */
4226        if (ret != 0) {
4227            RLOGE("error on reading command socket errno:%d\n", errno);
4228        } else {
4229            RLOGW("EOS.  Closing command socket.");
4230        }
4231
4232        close(fd);
4233        p_info->fdCommand = -1;
4234
4235        ril_event_del(p_info->commands_event);
4236
4237        record_stream_free(p_rs);
4238
4239        /* start listening for new connections again */
4240        rilEventAddWakeup(&s_listen_event);
4241
4242        onCommandsSocketClosed(p_info->socket_id);
4243    }
4244}
4245
4246
4247static void onNewCommandConnect(RIL_SOCKET_ID socket_id) {
4248    // Inform we are connected and the ril version
4249    int rilVer = s_callbacks.version;
4250    RIL_UNSOL_RESPONSE(RIL_UNSOL_RIL_CONNECTED,
4251                                    &rilVer, sizeof(rilVer), socket_id);
4252
4253    // implicit radio state changed
4254    RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
4255                                    NULL, 0, socket_id);
4256
4257    // Send last NITZ time data, in case it was missed
4258    if (s_lastNITZTimeData != NULL) {
4259        sendResponseRaw(s_lastNITZTimeData, s_lastNITZTimeDataSize, socket_id);
4260
4261        free(s_lastNITZTimeData);
4262        s_lastNITZTimeData = NULL;
4263    }
4264
4265    // Get version string
4266    if (s_callbacks.getVersion != NULL) {
4267        const char *version;
4268        version = s_callbacks.getVersion();
4269        RLOGI("RIL Daemon version: %s\n", version);
4270
4271        property_set(PROPERTY_RIL_IMPL, version);
4272    } else {
4273        RLOGI("RIL Daemon version: unavailable\n");
4274        property_set(PROPERTY_RIL_IMPL, "unavailable");
4275    }
4276
4277}
4278
4279static void listenCallback (int fd, short flags, void *param) {
4280    int ret;
4281    int err;
4282    int is_phone_socket;
4283    int fdCommand = -1;
4284    const char* processName;
4285    RecordStream *p_rs;
4286    MySocketListenParam* listenParam;
4287    RilSocket *sapSocket = NULL;
4288    socketClient *sClient = NULL;
4289
4290    SocketListenParam *p_info = (SocketListenParam *)param;
4291
4292    if(RIL_SAP_SOCKET == p_info->type) {
4293        listenParam = (MySocketListenParam *)param;
4294        sapSocket = listenParam->socket;
4295    }
4296
4297    struct sockaddr_un peeraddr;
4298    socklen_t socklen = sizeof (peeraddr);
4299
4300    struct ucred creds;
4301    socklen_t szCreds = sizeof(creds);
4302
4303    struct passwd *pwd = NULL;
4304
4305    if(NULL == sapSocket) {
4306        assert (*p_info->fdCommand < 0);
4307        assert (fd == *p_info->fdListen);
4308        processName = PHONE_PROCESS;
4309    } else {
4310        assert (sapSocket->commandFd < 0);
4311        assert (fd == sapSocket->listenFd);
4312        processName = BLUETOOTH_PROCESS;
4313    }
4314
4315
4316    fdCommand = accept(fd, (sockaddr *) &peeraddr, &socklen);
4317
4318    if (fdCommand < 0 ) {
4319        RLOGE("Error on accept() errno:%d", errno);
4320        /* start listening for new connections again */
4321        if(NULL == sapSocket) {
4322            rilEventAddWakeup(p_info->listen_event);
4323        } else {
4324            rilEventAddWakeup(sapSocket->getListenEvent());
4325        }
4326        return;
4327    }
4328
4329    /* check the credential of the other side and only accept socket from
4330     * phone process
4331     */
4332    errno = 0;
4333    is_phone_socket = 0;
4334
4335    err = getsockopt(fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds);
4336
4337    if (err == 0 && szCreds > 0) {
4338        errno = 0;
4339        pwd = getpwuid(creds.uid);
4340        if (pwd != NULL) {
4341            if (strcmp(pwd->pw_name, processName) == 0) {
4342                is_phone_socket = 1;
4343            } else {
4344                RLOGE("RILD can't accept socket from process %s", pwd->pw_name);
4345            }
4346        } else {
4347            RLOGE("Error on getpwuid() errno: %d", errno);
4348        }
4349    } else {
4350        RLOGD("Error on getsockopt() errno: %d", errno);
4351    }
4352
4353    if (!is_phone_socket) {
4354        RLOGE("RILD must accept socket from %s", processName);
4355
4356        close(fdCommand);
4357        fdCommand = -1;
4358
4359        if(NULL == sapSocket) {
4360            onCommandsSocketClosed(p_info->socket_id);
4361
4362            /* start listening for new connections again */
4363            rilEventAddWakeup(p_info->listen_event);
4364        } else {
4365            sapSocket->onCommandsSocketClosed();
4366
4367            /* start listening for new connections again */
4368            rilEventAddWakeup(sapSocket->getListenEvent());
4369        }
4370
4371        return;
4372    }
4373
4374    ret = fcntl(fdCommand, F_SETFL, O_NONBLOCK);
4375
4376    if (ret < 0) {
4377        RLOGE ("Error setting O_NONBLOCK errno:%d", errno);
4378    }
4379
4380    if(NULL == sapSocket) {
4381        RLOGI("libril: new connection to %s", rilSocketIdToString(p_info->socket_id));
4382
4383        p_info->fdCommand = fdCommand;
4384        p_rs = record_stream_new(p_info->fdCommand, MAX_COMMAND_BYTES);
4385        p_info->p_rs = p_rs;
4386
4387        ril_event_set (p_info->commands_event, p_info->fdCommand, 1,
4388        p_info->processCommandsCallback, p_info);
4389        rilEventAddWakeup (p_info->commands_event);
4390
4391        onNewCommandConnect(p_info->socket_id);
4392    } else {
4393        RLOGI("libril: new connection");
4394
4395        sapSocket->setCommandFd(fdCommand);
4396        p_rs = record_stream_new(sapSocket->getCommandFd(), MAX_COMMAND_BYTES);
4397        sClient = new socketClient(sapSocket,p_rs);
4398        ril_event_set (sapSocket->getCallbackEvent(), sapSocket->getCommandFd(), 1,
4399        sapSocket->getCommandCb(), sClient);
4400
4401        rilEventAddWakeup(sapSocket->getCallbackEvent());
4402        sapSocket->onNewCommandConnect();
4403    }
4404}
4405
4406static void freeDebugCallbackArgs(int number, char **args) {
4407    for (int i = 0; i < number; i++) {
4408        if (args[i] != NULL) {
4409            free(args[i]);
4410        }
4411    }
4412    free(args);
4413}
4414
4415static void debugCallback (int fd, short flags, void *param) {
4416    int acceptFD, option;
4417    struct sockaddr_un peeraddr;
4418    socklen_t socklen = sizeof (peeraddr);
4419    int data;
4420    unsigned int qxdm_data[6];
4421    const char *deactData[1] = {"1"};
4422    RIL_Dial dialData;
4423    int hangupData[1] = {1};
4424    int number;
4425    char **args;
4426    RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
4427    int MAX_DIAL_ADDRESS = 128;
4428    int sim_id = 0;
4429
4430    RLOGI("debugCallback for socket %s", rilSocketIdToString(socket_id));
4431
4432    acceptFD = accept (fd,  (sockaddr *) &peeraddr, &socklen);
4433
4434    if (acceptFD < 0) {
4435        RLOGE ("error accepting on debug port: %d\n", errno);
4436        return;
4437    }
4438
4439    if (recv(acceptFD, &number, sizeof(int), 0) != sizeof(int)) {
4440        RLOGE ("error reading on socket: number of Args: \n");
4441        close(acceptFD);
4442        return;
4443    }
4444
4445    if (number < 0) {
4446        RLOGE ("Invalid number of arguments: \n");
4447        close(acceptFD);
4448        return;
4449    }
4450
4451    args = (char **) calloc(number, sizeof(char*));
4452    if (args == NULL) {
4453        RLOGE("Memory allocation failed for debug args");
4454        close(acceptFD);
4455        return;
4456    }
4457
4458    for (int i = 0; i < number; i++) {
4459        int len;
4460        if (recv(acceptFD, &len, sizeof(int), 0) != sizeof(int)) {
4461            RLOGE ("error reading on socket: Len of Args: \n");
4462            freeDebugCallbackArgs(i, args);
4463            close(acceptFD);
4464            return;
4465        }
4466        if (len == INT_MAX || len < 0) {
4467            RLOGE("Invalid value of len: \n");
4468            freeDebugCallbackArgs(i, args);
4469            close(acceptFD);
4470            return;
4471        }
4472
4473        // +1 for null-term
4474        args[i] = (char *) calloc(len + 1, sizeof(char));
4475        if (args[i] == NULL) {
4476            RLOGE("Memory allocation failed for debug args");
4477            freeDebugCallbackArgs(i, args);
4478            close(acceptFD);
4479            return;
4480        }
4481        if (recv(acceptFD, args[i], sizeof(char) * len, 0)
4482            != (int)sizeof(char) * len) {
4483            RLOGE ("error reading on socket: Args[%d] \n", i);
4484            freeDebugCallbackArgs(i, args);
4485            close(acceptFD);
4486            return;
4487        }
4488        char * buf = args[i];
4489        buf[len] = 0;
4490        if ((i+1) == number) {
4491            /* The last argument should be sim id 0(SIM1)~3(SIM4) */
4492            sim_id = atoi(args[i]);
4493            switch (sim_id) {
4494                case 0:
4495                    socket_id = RIL_SOCKET_1;
4496                    break;
4497            #if (SIM_COUNT >= 2)
4498                case 1:
4499                    socket_id = RIL_SOCKET_2;
4500                    break;
4501            #endif
4502            #if (SIM_COUNT >= 3)
4503                case 2:
4504                    socket_id = RIL_SOCKET_3;
4505                    break;
4506            #endif
4507            #if (SIM_COUNT >= 4)
4508                case 3:
4509                    socket_id = RIL_SOCKET_4;
4510                    break;
4511            #endif
4512                default:
4513                    socket_id = RIL_SOCKET_1;
4514                    break;
4515            }
4516        }
4517    }
4518
4519    switch (atoi(args[0])) {
4520        case 0:
4521            RLOGI ("Connection on debug port: issuing reset.");
4522            issueLocalRequest(RIL_REQUEST_RESET_RADIO, NULL, 0, socket_id);
4523            break;
4524        case 1:
4525            RLOGI ("Connection on debug port: issuing radio power off.");
4526            data = 0;
4527            issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int), socket_id);
4528            // Close the socket
4529            if (socket_id == RIL_SOCKET_1 && s_ril_param_socket.fdCommand > 0) {
4530                close(s_ril_param_socket.fdCommand);
4531                s_ril_param_socket.fdCommand = -1;
4532            }
4533        #if (SIM_COUNT == 2)
4534            else if (socket_id == RIL_SOCKET_2 && s_ril_param_socket2.fdCommand > 0) {
4535                close(s_ril_param_socket2.fdCommand);
4536                s_ril_param_socket2.fdCommand = -1;
4537            }
4538        #endif
4539            break;
4540        case 2:
4541            RLOGI ("Debug port: issuing unsolicited voice network change.");
4542            RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, NULL, 0, socket_id);
4543            break;
4544        case 3:
4545            RLOGI ("Debug port: QXDM log enable.");
4546            qxdm_data[0] = 65536;     // head.func_tag
4547            qxdm_data[1] = 16;        // head.len
4548            qxdm_data[2] = 1;         // mode: 1 for 'start logging'
4549            qxdm_data[3] = 32;        // log_file_size: 32megabytes
4550            qxdm_data[4] = 0;         // log_mask
4551            qxdm_data[5] = 8;         // log_max_fileindex
4552            issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
4553                              6 * sizeof(int), socket_id);
4554            break;
4555        case 4:
4556            RLOGI ("Debug port: QXDM log disable.");
4557            qxdm_data[0] = 65536;
4558            qxdm_data[1] = 16;
4559            qxdm_data[2] = 0;          // mode: 0 for 'stop logging'
4560            qxdm_data[3] = 32;
4561            qxdm_data[4] = 0;
4562            qxdm_data[5] = 8;
4563            issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
4564                              6 * sizeof(int), socket_id);
4565            break;
4566        case 5:
4567            RLOGI("Debug port: Radio On");
4568            data = 1;
4569            issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int), socket_id);
4570            sleep(2);
4571            // Set network selection automatic.
4572            issueLocalRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, NULL, 0, socket_id);
4573            break;
4574        case 7:
4575            RLOGI("Debug port: Deactivate Data Call");
4576            issueLocalRequest(RIL_REQUEST_DEACTIVATE_DATA_CALL, &deactData,
4577                              sizeof(deactData), socket_id);
4578            break;
4579        case 8:
4580            RLOGI("Debug port: Dial Call");
4581            dialData.clir = 0;
4582            if (strlen(args[1]) > MAX_DIAL_ADDRESS) {
4583                RLOGE("Debug port: Error calling Dial");
4584                freeDebugCallbackArgs(number, args);
4585                close(acceptFD);
4586                return;
4587            }
4588            dialData.address = args[1];
4589            issueLocalRequest(RIL_REQUEST_DIAL, &dialData, sizeof(dialData), socket_id);
4590            break;
4591        case 9:
4592            RLOGI("Debug port: Answer Call");
4593            issueLocalRequest(RIL_REQUEST_ANSWER, NULL, 0, socket_id);
4594            break;
4595        case 10:
4596            RLOGI("Debug port: End Call");
4597            issueLocalRequest(RIL_REQUEST_HANGUP, &hangupData,
4598                              sizeof(hangupData), socket_id);
4599            break;
4600        default:
4601            RLOGE ("Invalid request");
4602            break;
4603    }
4604    freeDebugCallbackArgs(number, args);
4605    close(acceptFD);
4606}
4607
4608
4609static void userTimerCallback (int fd, short flags, void *param) {
4610    UserCallbackInfo *p_info;
4611
4612    p_info = (UserCallbackInfo *)param;
4613
4614    p_info->p_callback(p_info->userParam);
4615
4616
4617    // FIXME generalize this...there should be a cancel mechanism
4618    if (s_last_wake_timeout_info != NULL && s_last_wake_timeout_info == p_info) {
4619        s_last_wake_timeout_info = NULL;
4620    }
4621
4622    free(p_info);
4623}
4624
4625
4626static void *
4627eventLoop(void *param) {
4628    int ret;
4629    int filedes[2];
4630
4631    ril_event_init();
4632
4633    pthread_mutex_lock(&s_startupMutex);
4634
4635    s_started = 1;
4636    pthread_cond_broadcast(&s_startupCond);
4637
4638    pthread_mutex_unlock(&s_startupMutex);
4639
4640    ret = pipe(filedes);
4641
4642    if (ret < 0) {
4643        RLOGE("Error in pipe() errno:%d", errno);
4644        return NULL;
4645    }
4646
4647    s_fdWakeupRead = filedes[0];
4648    s_fdWakeupWrite = filedes[1];
4649
4650    fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
4651
4652    ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
4653                processWakeupCallback, NULL);
4654
4655    rilEventAddWakeup (&s_wakeupfd_event);
4656
4657    // Only returns on error
4658    ril_event_loop();
4659    RLOGE ("error in event_loop_base errno:%d", errno);
4660    // kill self to restart on error
4661    kill(0, SIGKILL);
4662
4663    return NULL;
4664}
4665
4666extern "C" void
4667RIL_startEventLoop(void) {
4668    /* spin up eventLoop thread and wait for it to get started */
4669    s_started = 0;
4670    pthread_mutex_lock(&s_startupMutex);
4671
4672    pthread_attr_t attr;
4673    pthread_attr_init(&attr);
4674    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4675
4676    int result = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
4677    if (result != 0) {
4678        RLOGE("Failed to create dispatch thread: %s", strerror(result));
4679        goto done;
4680    }
4681
4682    while (s_started == 0) {
4683        pthread_cond_wait(&s_startupCond, &s_startupMutex);
4684    }
4685
4686done:
4687    pthread_mutex_unlock(&s_startupMutex);
4688}
4689
4690// Used for testing purpose only.
4691extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) {
4692    memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
4693}
4694
4695static void startListen(RIL_SOCKET_ID socket_id, SocketListenParam* socket_listen_p) {
4696    int fdListen = -1;
4697    int ret;
4698    char socket_name[10];
4699
4700    memset(socket_name, 0, sizeof(char)*10);
4701
4702    switch(socket_id) {
4703        case RIL_SOCKET_1:
4704            strncpy(socket_name, RIL_getRilSocketName(), 9);
4705            break;
4706    #if (SIM_COUNT >= 2)
4707        case RIL_SOCKET_2:
4708            strncpy(socket_name, SOCKET2_NAME_RIL, 9);
4709            break;
4710    #endif
4711    #if (SIM_COUNT >= 3)
4712        case RIL_SOCKET_3:
4713            strncpy(socket_name, SOCKET3_NAME_RIL, 9);
4714            break;
4715    #endif
4716    #if (SIM_COUNT >= 4)
4717        case RIL_SOCKET_4:
4718            strncpy(socket_name, SOCKET4_NAME_RIL, 9);
4719            break;
4720    #endif
4721        default:
4722            RLOGE("Socket id is wrong!!");
4723            return;
4724    }
4725
4726    RLOGI("Start to listen %s", rilSocketIdToString(socket_id));
4727
4728    fdListen = android_get_control_socket(socket_name);
4729    if (fdListen < 0) {
4730        RLOGE("Failed to get socket %s", socket_name);
4731        exit(-1);
4732    }
4733
4734    ret = listen(fdListen, 4);
4735
4736    if (ret < 0) {
4737        RLOGE("Failed to listen on control socket '%d': %s",
4738             fdListen, strerror(errno));
4739        exit(-1);
4740    }
4741    socket_listen_p->fdListen = fdListen;
4742
4743    /* note: non-persistent so we can accept only one connection at a time */
4744    ril_event_set (socket_listen_p->listen_event, fdListen, false,
4745                listenCallback, socket_listen_p);
4746
4747    rilEventAddWakeup (socket_listen_p->listen_event);
4748}
4749
4750extern "C" void
4751RIL_register (const RIL_RadioFunctions *callbacks) {
4752    int ret;
4753    int flags;
4754
4755    RLOGI("SIM_COUNT: %d", SIM_COUNT);
4756
4757    if (callbacks == NULL) {
4758        RLOGE("RIL_register: RIL_RadioFunctions * null");
4759        return;
4760    }
4761    if (callbacks->version < RIL_VERSION_MIN) {
4762        RLOGE("RIL_register: version %d is to old, min version is %d",
4763             callbacks->version, RIL_VERSION_MIN);
4764        return;
4765    }
4766
4767    RLOGE("RIL_register: RIL version %d", callbacks->version);
4768
4769    if (s_registerCalled > 0) {
4770        RLOGE("RIL_register has been called more than once. "
4771                "Subsequent call ignored");
4772        return;
4773    }
4774
4775    memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
4776
4777    /* Initialize socket1 parameters */
4778    s_ril_param_socket = {
4779                        RIL_SOCKET_1,             /* socket_id */
4780                        -1,                       /* fdListen */
4781                        -1,                       /* fdCommand */
4782                        PHONE_PROCESS,            /* processName */
4783                        &s_commands_event,        /* commands_event */
4784                        &s_listen_event,          /* listen_event */
4785                        processCommandsCallback,  /* processCommandsCallback */
4786                        NULL,                     /* p_rs */
4787                        RIL_TELEPHONY_SOCKET      /* type */
4788                        };
4789
4790#if (SIM_COUNT >= 2)
4791    s_ril_param_socket2 = {
4792                        RIL_SOCKET_2,               /* socket_id */
4793                        -1,                         /* fdListen */
4794                        -1,                         /* fdCommand */
4795                        PHONE_PROCESS,              /* processName */
4796                        &s_commands_event_socket2,  /* commands_event */
4797                        &s_listen_event_socket2,    /* listen_event */
4798                        processCommandsCallback,    /* processCommandsCallback */
4799                        NULL,                       /* p_rs */
4800                        RIL_TELEPHONY_SOCKET        /* type */
4801                        };
4802#endif
4803
4804#if (SIM_COUNT >= 3)
4805    s_ril_param_socket3 = {
4806                        RIL_SOCKET_3,               /* socket_id */
4807                        -1,                         /* fdListen */
4808                        -1,                         /* fdCommand */
4809                        PHONE_PROCESS,              /* processName */
4810                        &s_commands_event_socket3,  /* commands_event */
4811                        &s_listen_event_socket3,    /* listen_event */
4812                        processCommandsCallback,    /* processCommandsCallback */
4813                        NULL,                       /* p_rs */
4814                        RIL_TELEPHONY_SOCKET        /* type */
4815                        };
4816#endif
4817
4818#if (SIM_COUNT >= 4)
4819    s_ril_param_socket4 = {
4820                        RIL_SOCKET_4,               /* socket_id */
4821                        -1,                         /* fdListen */
4822                        -1,                         /* fdCommand */
4823                        PHONE_PROCESS,              /* processName */
4824                        &s_commands_event_socket4,  /* commands_event */
4825                        &s_listen_event_socket4,    /* listen_event */
4826                        processCommandsCallback,    /* processCommandsCallback */
4827                        NULL,                       /* p_rs */
4828                        RIL_TELEPHONY_SOCKET        /* type */
4829                        };
4830#endif
4831
4832
4833    s_registerCalled = 1;
4834
4835    RLOGI("s_registerCalled flag set, %d", s_started);
4836    // Little self-check
4837
4838    for (int i = 0; i < (int)NUM_ELEMS(s_commands); i++) {
4839        assert(i == s_commands[i].requestNumber);
4840    }
4841
4842    for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses); i++) {
4843        assert(i + RIL_UNSOL_RESPONSE_BASE
4844                == s_unsolResponses[i].requestNumber);
4845    }
4846
4847    // New rild impl calls RIL_startEventLoop() first
4848    // old standalone impl wants it here.
4849
4850    if (s_started == 0) {
4851        RIL_startEventLoop();
4852    }
4853
4854    // start listen socket1
4855    startListen(RIL_SOCKET_1, &s_ril_param_socket);
4856
4857#if (SIM_COUNT >= 2)
4858    // start listen socket2
4859    startListen(RIL_SOCKET_2, &s_ril_param_socket2);
4860#endif /* (SIM_COUNT == 2) */
4861
4862#if (SIM_COUNT >= 3)
4863    // start listen socket3
4864    startListen(RIL_SOCKET_3, &s_ril_param_socket3);
4865#endif /* (SIM_COUNT == 3) */
4866
4867#if (SIM_COUNT >= 4)
4868    // start listen socket4
4869    startListen(RIL_SOCKET_4, &s_ril_param_socket4);
4870#endif /* (SIM_COUNT == 4) */
4871
4872
4873#if 1
4874    // start debug interface socket
4875
4876    char *inst = NULL;
4877    if (strlen(RIL_getRilSocketName()) >= strlen(SOCKET_NAME_RIL)) {
4878        inst = RIL_getRilSocketName() + strlen(SOCKET_NAME_RIL);
4879    }
4880
4881    char rildebug[MAX_DEBUG_SOCKET_NAME_LENGTH] = SOCKET_NAME_RIL_DEBUG;
4882    if (inst != NULL) {
4883        strlcat(rildebug, inst, MAX_DEBUG_SOCKET_NAME_LENGTH);
4884    }
4885
4886    s_fdDebug = android_get_control_socket(rildebug);
4887    if (s_fdDebug < 0) {
4888        RLOGE("Failed to get socket : %s errno:%d", rildebug, errno);
4889        exit(-1);
4890    }
4891
4892    ret = listen(s_fdDebug, 4);
4893
4894    if (ret < 0) {
4895        RLOGE("Failed to listen on ril debug socket '%d': %s",
4896             s_fdDebug, strerror(errno));
4897        exit(-1);
4898    }
4899
4900    ril_event_set (&s_debug_event, s_fdDebug, true,
4901                debugCallback, NULL);
4902
4903    rilEventAddWakeup (&s_debug_event);
4904#endif
4905
4906}
4907
4908extern "C" void
4909RIL_register_socket (RIL_RadioFunctions *(*Init)(const struct RIL_Env *, int, char **),RIL_SOCKET_TYPE socketType, int argc, char **argv) {
4910
4911    RIL_RadioFunctions* UimFuncs = NULL;
4912
4913    if(Init) {
4914        UimFuncs = Init(&RilSapSocket::uimRilEnv, argc, argv);
4915
4916        switch(socketType) {
4917            case RIL_SAP_SOCKET:
4918                RilSapSocket::initSapSocket("sap_uim_socket1", UimFuncs);
4919
4920#if (SIM_COUNT >= 2)
4921                RilSapSocket::initSapSocket("sap_uim_socket2", UimFuncs);
4922#endif
4923
4924#if (SIM_COUNT >= 3)
4925                RilSapSocket::initSapSocket("sap_uim_socket3", UimFuncs);
4926#endif
4927
4928#if (SIM_COUNT >= 4)
4929                RilSapSocket::initSapSocket("sap_uim_socket4", UimFuncs);
4930#endif
4931                break;
4932            default:;
4933        }
4934    }
4935}
4936
4937// Check and remove RequestInfo if its a response and not just ack sent back
4938static int
4939checkAndDequeueRequestInfoIfAck(struct RequestInfo *pRI, bool isAck) {
4940    int ret = 0;
4941    /* Hook for current context
4942       pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
4943    pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
4944    /* pendingRequestsHook refer to &s_pendingRequests */
4945    RequestInfo ** pendingRequestsHook = &s_pendingRequests;
4946
4947    if (pRI == NULL) {
4948        return 0;
4949    }
4950
4951#if (SIM_COUNT >= 2)
4952    if (pRI->socket_id == RIL_SOCKET_2) {
4953        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
4954        pendingRequestsHook = &s_pendingRequests_socket2;
4955    }
4956#if (SIM_COUNT >= 3)
4957        if (pRI->socket_id == RIL_SOCKET_3) {
4958            pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
4959            pendingRequestsHook = &s_pendingRequests_socket3;
4960        }
4961#endif
4962#if (SIM_COUNT >= 4)
4963    if (pRI->socket_id == RIL_SOCKET_4) {
4964        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
4965        pendingRequestsHook = &s_pendingRequests_socket4;
4966    }
4967#endif
4968#endif
4969    pthread_mutex_lock(pendingRequestsMutexHook);
4970
4971    for(RequestInfo **ppCur = pendingRequestsHook
4972        ; *ppCur != NULL
4973        ; ppCur = &((*ppCur)->p_next)
4974    ) {
4975        if (pRI == *ppCur) {
4976            ret = 1;
4977            if (isAck) { // Async ack
4978                if (pRI->wasAckSent == 1) {
4979                    RLOGD("Ack was already sent for %s", requestToString(pRI->pCI->requestNumber));
4980                } else {
4981                    pRI->wasAckSent = 1;
4982                }
4983            } else {
4984                *ppCur = (*ppCur)->p_next;
4985            }
4986            break;
4987        }
4988    }
4989
4990    pthread_mutex_unlock(pendingRequestsMutexHook);
4991
4992    return ret;
4993}
4994
4995static int findFd(int socket_id) {
4996    int fd = s_ril_param_socket.fdCommand;
4997#if (SIM_COUNT >= 2)
4998    if (socket_id == RIL_SOCKET_2) {
4999        fd = s_ril_param_socket2.fdCommand;
5000    }
5001#if (SIM_COUNT >= 3)
5002    if (socket_id == RIL_SOCKET_3) {
5003        fd = s_ril_param_socket3.fdCommand;
5004    }
5005#endif
5006#if (SIM_COUNT >= 4)
5007    if (socket_id == RIL_SOCKET_4) {
5008        fd = s_ril_param_socket4.fdCommand;
5009    }
5010#endif
5011#endif
5012    return fd;
5013}
5014
5015extern "C" void
5016RIL_onRequestAck(RIL_Token t) {
5017    RequestInfo *pRI;
5018    int ret, fd;
5019
5020    size_t errorOffset;
5021    RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
5022
5023    pRI = (RequestInfo *)t;
5024
5025    if (!checkAndDequeueRequestInfoIfAck(pRI, true)) {
5026        RLOGE ("RIL_onRequestAck: invalid RIL_Token");
5027        return;
5028    }
5029
5030    socket_id = pRI->socket_id;
5031    fd = findFd(socket_id);
5032
5033#if VDBG
5034    RLOGD("Request Ack, %s", rilSocketIdToString(socket_id));
5035#endif
5036
5037    appendPrintBuf("Ack [%04d]< %s", pRI->token, requestToString(pRI->pCI->requestNumber));
5038
5039    if (pRI->cancelled == 0) {
5040        Parcel p;
5041
5042        p.writeInt32 (RESPONSE_SOLICITED_ACK);
5043        p.writeInt32 (pRI->token);
5044
5045        if (fd < 0) {
5046            RLOGD ("RIL onRequestComplete: Command channel closed");
5047        }
5048
5049        sendResponse(p, socket_id);
5050    }
5051}
5052
5053extern "C" void
5054RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
5055    RequestInfo *pRI;
5056    int ret;
5057    int fd;
5058    size_t errorOffset;
5059    RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
5060
5061    pRI = (RequestInfo *)t;
5062
5063    if (!checkAndDequeueRequestInfoIfAck(pRI, false)) {
5064        RLOGE ("RIL_onRequestComplete: invalid RIL_Token");
5065        return;
5066    }
5067
5068    socket_id = pRI->socket_id;
5069    fd = findFd(socket_id);
5070
5071#if VDBG
5072    RLOGD("RequestComplete, %s", rilSocketIdToString(socket_id));
5073#endif
5074
5075    if (pRI->local > 0) {
5076        // Locally issued command...void only!
5077        // response does not go back up the command socket
5078        RLOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
5079
5080        goto done;
5081    }
5082
5083    appendPrintBuf("[%04d]< %s",
5084        pRI->token, requestToString(pRI->pCI->requestNumber));
5085
5086    if (pRI->cancelled == 0) {
5087        Parcel p;
5088
5089        if (s_callbacks.version >= 13 && pRI->wasAckSent == 1) {
5090            // If ack was already sent, then this call is an asynchronous response. So we need to
5091            // send id indicating that we expect an ack from RIL.java as we acquire wakelock here.
5092            p.writeInt32 (RESPONSE_SOLICITED_ACK_EXP);
5093            grabPartialWakeLock();
5094        } else {
5095            p.writeInt32 (RESPONSE_SOLICITED);
5096        }
5097        p.writeInt32 (pRI->token);
5098        errorOffset = p.dataPosition();
5099
5100        p.writeInt32 (e);
5101
5102        if (response != NULL) {
5103            // there is a response payload, no matter success or not.
5104            ret = pRI->pCI->responseFunction(p, response, responselen);
5105
5106            /* if an error occurred, rewind and mark it */
5107            if (ret != 0) {
5108                RLOGE ("responseFunction error, ret %d", ret);
5109                p.setDataPosition(errorOffset);
5110                p.writeInt32 (ret);
5111            }
5112        }
5113
5114        if (e != RIL_E_SUCCESS) {
5115            appendPrintBuf("%s fails by %s", printBuf, failCauseToString(e));
5116        }
5117
5118        if (fd < 0) {
5119            RLOGD ("RIL onRequestComplete: Command channel closed");
5120        }
5121        sendResponse(p, socket_id);
5122    }
5123
5124done:
5125    free(pRI);
5126}
5127
5128static void
5129grabPartialWakeLock() {
5130    if (s_callbacks.version >= 13) {
5131        int ret;
5132        ret = pthread_mutex_lock(&s_wakeLockCountMutex);
5133        assert(ret == 0);
5134        acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
5135
5136        UserCallbackInfo *p_info =
5137                internalRequestTimedCallback(wakeTimeoutCallback, NULL, &TIMEVAL_WAKE_TIMEOUT);
5138        if (p_info == NULL) {
5139            release_wake_lock(ANDROID_WAKE_LOCK_NAME);
5140        } else {
5141            s_wakelock_count++;
5142            if (s_last_wake_timeout_info != NULL) {
5143                s_last_wake_timeout_info->userParam = (void *)1;
5144            }
5145            s_last_wake_timeout_info = p_info;
5146        }
5147        ret = pthread_mutex_unlock(&s_wakeLockCountMutex);
5148        assert(ret == 0);
5149    } else {
5150        acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
5151    }
5152}
5153
5154static void
5155releaseWakeLock() {
5156    if (s_callbacks.version >= 13) {
5157        int ret;
5158        ret = pthread_mutex_lock(&s_wakeLockCountMutex);
5159        assert(ret == 0);
5160
5161        if (s_wakelock_count > 1) {
5162            s_wakelock_count--;
5163        } else {
5164            s_wakelock_count = 0;
5165            release_wake_lock(ANDROID_WAKE_LOCK_NAME);
5166            if (s_last_wake_timeout_info != NULL) {
5167                s_last_wake_timeout_info->userParam = (void *)1;
5168            }
5169        }
5170
5171        ret = pthread_mutex_unlock(&s_wakeLockCountMutex);
5172        assert(ret == 0);
5173    } else {
5174        release_wake_lock(ANDROID_WAKE_LOCK_NAME);
5175    }
5176}
5177
5178/**
5179 * Timer callback to put us back to sleep before the default timeout
5180 */
5181static void
5182wakeTimeoutCallback (void *param) {
5183    // We're using "param != NULL" as a cancellation mechanism
5184    if (s_callbacks.version >= 13) {
5185        if (param == NULL) {
5186            int ret;
5187            ret = pthread_mutex_lock(&s_wakeLockCountMutex);
5188            assert(ret == 0);
5189            s_wakelock_count = 0;
5190            release_wake_lock(ANDROID_WAKE_LOCK_NAME);
5191            ret = pthread_mutex_unlock(&s_wakeLockCountMutex);
5192            assert(ret == 0);
5193        }
5194    } else {
5195        if (param == NULL) {
5196            releaseWakeLock();
5197        }
5198    }
5199}
5200
5201static int
5202decodeVoiceRadioTechnology (RIL_RadioState radioState) {
5203    switch (radioState) {
5204        case RADIO_STATE_SIM_NOT_READY:
5205        case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
5206        case RADIO_STATE_SIM_READY:
5207            return RADIO_TECH_UMTS;
5208
5209        case RADIO_STATE_RUIM_NOT_READY:
5210        case RADIO_STATE_RUIM_READY:
5211        case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
5212        case RADIO_STATE_NV_NOT_READY:
5213        case RADIO_STATE_NV_READY:
5214            return RADIO_TECH_1xRTT;
5215
5216        default:
5217            RLOGD("decodeVoiceRadioTechnology: Invoked with incorrect RadioState");
5218            return -1;
5219    }
5220}
5221
5222static int
5223decodeCdmaSubscriptionSource (RIL_RadioState radioState) {
5224    switch (radioState) {
5225        case RADIO_STATE_SIM_NOT_READY:
5226        case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
5227        case RADIO_STATE_SIM_READY:
5228        case RADIO_STATE_RUIM_NOT_READY:
5229        case RADIO_STATE_RUIM_READY:
5230        case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
5231            return CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM;
5232
5233        case RADIO_STATE_NV_NOT_READY:
5234        case RADIO_STATE_NV_READY:
5235            return CDMA_SUBSCRIPTION_SOURCE_NV;
5236
5237        default:
5238            RLOGD("decodeCdmaSubscriptionSource: Invoked with incorrect RadioState");
5239            return -1;
5240    }
5241}
5242
5243static int
5244decodeSimStatus (RIL_RadioState radioState) {
5245   switch (radioState) {
5246       case RADIO_STATE_SIM_NOT_READY:
5247       case RADIO_STATE_RUIM_NOT_READY:
5248       case RADIO_STATE_NV_NOT_READY:
5249       case RADIO_STATE_NV_READY:
5250           return -1;
5251       case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
5252       case RADIO_STATE_SIM_READY:
5253       case RADIO_STATE_RUIM_READY:
5254       case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
5255           return radioState;
5256       default:
5257           RLOGD("decodeSimStatus: Invoked with incorrect RadioState");
5258           return -1;
5259   }
5260}
5261
5262static bool is3gpp2(int radioTech) {
5263    switch (radioTech) {
5264        case RADIO_TECH_IS95A:
5265        case RADIO_TECH_IS95B:
5266        case RADIO_TECH_1xRTT:
5267        case RADIO_TECH_EVDO_0:
5268        case RADIO_TECH_EVDO_A:
5269        case RADIO_TECH_EVDO_B:
5270        case RADIO_TECH_EHRPD:
5271            return true;
5272        default:
5273            return false;
5274    }
5275}
5276
5277/* If RIL sends SIM states or RUIM states, store the voice radio
5278 * technology and subscription source information so that they can be
5279 * returned when telephony framework requests them
5280 */
5281static RIL_RadioState
5282processRadioState(RIL_RadioState newRadioState, RIL_SOCKET_ID socket_id) {
5283
5284    if((newRadioState > RADIO_STATE_UNAVAILABLE) && (newRadioState < RADIO_STATE_ON)) {
5285        int newVoiceRadioTech;
5286        int newCdmaSubscriptionSource;
5287        int newSimStatus;
5288
5289        /* This is old RIL. Decode Subscription source and Voice Radio Technology
5290           from Radio State and send change notifications if there has been a change */
5291        newVoiceRadioTech = decodeVoiceRadioTechnology(newRadioState);
5292        if(newVoiceRadioTech != voiceRadioTech) {
5293            voiceRadioTech = newVoiceRadioTech;
5294            RIL_UNSOL_RESPONSE(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED,
5295                        &voiceRadioTech, sizeof(voiceRadioTech), socket_id);
5296        }
5297        if(is3gpp2(newVoiceRadioTech)) {
5298            newCdmaSubscriptionSource = decodeCdmaSubscriptionSource(newRadioState);
5299            if(newCdmaSubscriptionSource != cdmaSubscriptionSource) {
5300                cdmaSubscriptionSource = newCdmaSubscriptionSource;
5301                RIL_UNSOL_RESPONSE(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED,
5302                        &cdmaSubscriptionSource, sizeof(cdmaSubscriptionSource), socket_id);
5303            }
5304        }
5305        newSimStatus = decodeSimStatus(newRadioState);
5306        if(newSimStatus != simRuimStatus) {
5307            simRuimStatus = newSimStatus;
5308            RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0, socket_id);
5309        }
5310
5311        /* Send RADIO_ON to telephony */
5312        newRadioState = RADIO_STATE_ON;
5313    }
5314
5315    return newRadioState;
5316}
5317
5318
5319#if defined(ANDROID_MULTI_SIM)
5320extern "C"
5321void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
5322                                size_t datalen, RIL_SOCKET_ID socket_id)
5323#else
5324extern "C"
5325void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
5326                                size_t datalen)
5327#endif
5328{
5329    int unsolResponseIndex;
5330    int ret;
5331    int64_t timeReceived = 0;
5332    bool shouldScheduleTimeout = false;
5333    RIL_RadioState newState;
5334    RIL_SOCKET_ID soc_id = RIL_SOCKET_1;
5335
5336#if defined(ANDROID_MULTI_SIM)
5337    soc_id = socket_id;
5338#endif
5339
5340
5341    if (s_registerCalled == 0) {
5342        // Ignore RIL_onUnsolicitedResponse before RIL_register
5343        RLOGW("RIL_onUnsolicitedResponse called before RIL_register");
5344        return;
5345    }
5346
5347    unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
5348
5349    if ((unsolResponseIndex < 0)
5350        || (unsolResponseIndex >= (int32_t)NUM_ELEMS(s_unsolResponses))) {
5351        RLOGE("unsupported unsolicited response code %d", unsolResponse);
5352        return;
5353    }
5354
5355    // Grab a wake lock if needed for this reponse,
5356    // as we exit we'll either release it immediately
5357    // or set a timer to release it later.
5358    switch (s_unsolResponses[unsolResponseIndex].wakeType) {
5359        case WAKE_PARTIAL:
5360            grabPartialWakeLock();
5361            shouldScheduleTimeout = true;
5362        break;
5363
5364        case DONT_WAKE:
5365        default:
5366            // No wake lock is grabed so don't set timeout
5367            shouldScheduleTimeout = false;
5368            break;
5369    }
5370
5371    // Mark the time this was received, doing this
5372    // after grabing the wakelock incase getting
5373    // the elapsedRealTime might cause us to goto
5374    // sleep.
5375    if (unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
5376        timeReceived = elapsedRealtime();
5377    }
5378
5379    appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
5380
5381    Parcel p;
5382    if (s_callbacks.version >= 13
5383                && s_unsolResponses[unsolResponseIndex].wakeType == WAKE_PARTIAL) {
5384        p.writeInt32 (RESPONSE_UNSOLICITED_ACK_EXP);
5385    } else {
5386        p.writeInt32 (RESPONSE_UNSOLICITED);
5387    }
5388    p.writeInt32 (unsolResponse);
5389
5390    ret = s_unsolResponses[unsolResponseIndex]
5391                .responseFunction(p, const_cast<void*>(data), datalen);
5392    if (ret != 0) {
5393        // Problem with the response. Don't continue;
5394        goto error_exit;
5395    }
5396
5397    // some things get more payload
5398    switch(unsolResponse) {
5399        case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
5400            newState = processRadioState(CALL_ONSTATEREQUEST(soc_id), soc_id);
5401            p.writeInt32(newState);
5402            appendPrintBuf("%s {%s}", printBuf,
5403                radioStateToString(CALL_ONSTATEREQUEST(soc_id)));
5404        break;
5405
5406
5407        case RIL_UNSOL_NITZ_TIME_RECEIVED:
5408            // Store the time that this was received so the
5409            // handler of this message can account for
5410            // the time it takes to arrive and process. In
5411            // particular the system has been known to sleep
5412            // before this message can be processed.
5413            p.writeInt64(timeReceived);
5414        break;
5415    }
5416
5417    if (s_callbacks.version < 13) {
5418        if (shouldScheduleTimeout) {
5419            UserCallbackInfo *p_info = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
5420                    &TIMEVAL_WAKE_TIMEOUT);
5421
5422            if (p_info == NULL) {
5423                goto error_exit;
5424            } else {
5425                // Cancel the previous request
5426                if (s_last_wake_timeout_info != NULL) {
5427                    s_last_wake_timeout_info->userParam = (void *)1;
5428                }
5429                s_last_wake_timeout_info = p_info;
5430            }
5431        }
5432    }
5433
5434#if VDBG
5435    RLOGI("%s UNSOLICITED: %s length:%d", rilSocketIdToString(soc_id), requestToString(unsolResponse), p.dataSize());
5436#endif
5437    ret = sendResponse(p, soc_id);
5438    if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
5439
5440        // Unfortunately, NITZ time is not poll/update like everything
5441        // else in the system. So, if the upstream client isn't connected,
5442        // keep a copy of the last NITZ response (with receive time noted
5443        // above) around so we can deliver it when it is connected
5444
5445        if (s_lastNITZTimeData != NULL) {
5446            free (s_lastNITZTimeData);
5447            s_lastNITZTimeData = NULL;
5448        }
5449
5450        s_lastNITZTimeData = calloc(p.dataSize(), 1);
5451        if (s_lastNITZTimeData == NULL) {
5452             RLOGE("Memory allocation failed in RIL_onUnsolicitedResponse");
5453             goto error_exit;
5454        }
5455        s_lastNITZTimeDataSize = p.dataSize();
5456        memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
5457    }
5458
5459    // Normal exit
5460    return;
5461
5462error_exit:
5463    if (shouldScheduleTimeout) {
5464        releaseWakeLock();
5465    }
5466}
5467
5468/** FIXME generalize this if you track UserCAllbackInfo, clear it
5469    when the callback occurs
5470*/
5471static UserCallbackInfo *
5472internalRequestTimedCallback (RIL_TimedCallback callback, void *param,
5473                                const struct timeval *relativeTime)
5474{
5475    struct timeval myRelativeTime;
5476    UserCallbackInfo *p_info;
5477
5478    p_info = (UserCallbackInfo *) calloc(1, sizeof(UserCallbackInfo));
5479    if (p_info == NULL) {
5480        RLOGE("Memory allocation failed in internalRequestTimedCallback");
5481        return p_info;
5482
5483    }
5484
5485    p_info->p_callback = callback;
5486    p_info->userParam = param;
5487
5488    if (relativeTime == NULL) {
5489        /* treat null parameter as a 0 relative time */
5490        memset (&myRelativeTime, 0, sizeof(myRelativeTime));
5491    } else {
5492        /* FIXME I think event_add's tv param is really const anyway */
5493        memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime));
5494    }
5495
5496    ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info);
5497
5498    ril_timer_add(&(p_info->event), &myRelativeTime);
5499
5500    triggerEvLoop();
5501    return p_info;
5502}
5503
5504
5505extern "C" void
5506RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
5507                                const struct timeval *relativeTime) {
5508    internalRequestTimedCallback (callback, param, relativeTime);
5509}
5510
5511const char *
5512failCauseToString(RIL_Errno e) {
5513    switch(e) {
5514        case RIL_E_SUCCESS: return "E_SUCCESS";
5515        case RIL_E_RADIO_NOT_AVAILABLE: return "E_RADIO_NOT_AVAILABLE";
5516        case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE";
5517        case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT";
5518        case RIL_E_SIM_PIN2: return "E_SIM_PIN2";
5519        case RIL_E_SIM_PUK2: return "E_SIM_PUK2";
5520        case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED";
5521        case RIL_E_CANCELLED: return "E_CANCELLED";
5522        case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL";
5523        case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW";
5524        case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY";
5525        case RIL_E_SIM_ABSENT:return "E_SIM_ABSENT";
5526        case RIL_E_ILLEGAL_SIM_OR_ME:return "E_ILLEGAL_SIM_OR_ME";
5527#ifdef FEATURE_MULTIMODE_ANDROID
5528        case RIL_E_SUBSCRIPTION_NOT_AVAILABLE:return "E_SUBSCRIPTION_NOT_AVAILABLE";
5529        case RIL_E_MODE_NOT_SUPPORTED:return "E_MODE_NOT_SUPPORTED";
5530#endif
5531        case RIL_E_FDN_CHECK_FAILURE: return "E_FDN_CHECK_FAILURE";
5532        case RIL_E_MISSING_RESOURCE: return "E_MISSING_RESOURCE";
5533        case RIL_E_NO_SUCH_ELEMENT: return "E_NO_SUCH_ELEMENT";
5534        case RIL_E_DIAL_MODIFIED_TO_USSD: return "E_DIAL_MODIFIED_TO_USSD";
5535        case RIL_E_DIAL_MODIFIED_TO_SS: return "E_DIAL_MODIFIED_TO_SS";
5536        case RIL_E_DIAL_MODIFIED_TO_DIAL: return "E_DIAL_MODIFIED_TO_DIAL";
5537        case RIL_E_USSD_MODIFIED_TO_DIAL: return "E_USSD_MODIFIED_TO_DIAL";
5538        case RIL_E_USSD_MODIFIED_TO_SS: return "E_USSD_MODIFIED_TO_SS";
5539        case RIL_E_USSD_MODIFIED_TO_USSD: return "E_USSD_MODIFIED_TO_USSD";
5540        case RIL_E_SS_MODIFIED_TO_DIAL: return "E_SS_MODIFIED_TO_DIAL";
5541        case RIL_E_SS_MODIFIED_TO_USSD: return "E_SS_MODIFIED_TO_USSD";
5542        case RIL_E_SUBSCRIPTION_NOT_SUPPORTED: return "E_SUBSCRIPTION_NOT_SUPPORTED";
5543        case RIL_E_SS_MODIFIED_TO_SS: return "E_SS_MODIFIED_TO_SS";
5544        case RIL_E_LCE_NOT_SUPPORTED: return "E_LCE_NOT_SUPPORTED";
5545        case RIL_E_NO_MEMORY: return "E_NO_MEMORY";
5546        case RIL_E_INTERNAL_ERR: return "E_INTERNAL_ERR";
5547        case RIL_E_SYSTEM_ERR: return "E_SYSTEM_ERR";
5548        case RIL_E_MODEM_ERR: return "E_MODEM_ERR";
5549        case RIL_E_INVALID_STATE: return "E_INVALID_STATE";
5550        case RIL_E_NO_RESOURCES: return "E_NO_RESOURCES";
5551        case RIL_E_SIM_ERR: return "E_SIM_ERR";
5552        case RIL_E_INVALID_ARGUMENTS: return "E_INVALID_ARGUMENTS";
5553        case RIL_E_INVALID_SIM_STATE: return "E_INVALID_SIM_STATE";
5554        case RIL_E_INVALID_MODEM_STATE: return "E_INVALID_MODEM_STATE";
5555        case RIL_E_INVALID_CALL_ID: return "E_INVALID_CALL_ID";
5556        case RIL_E_NO_SMS_TO_ACK: return "E_NO_SMS_TO_ACK";
5557        case RIL_E_NETWORK_ERR: return "E_NETWORK_ERR";
5558        case RIL_E_REQUEST_RATE_LIMITED: return "E_REQUEST_RATE_LIMITED";
5559        case RIL_E_SIM_BUSY: return "E_SIM_BUSY";
5560        case RIL_E_SIM_FULL: return "E_SIM_FULL";
5561        case RIL_E_NETWORK_REJECT: return "E_NETWORK_REJECT";
5562        case RIL_E_OPERATION_NOT_ALLOWED: return "E_OPERATION_NOT_ALLOWED";
5563        case RIL_E_EMPTY_RECORD: "E_EMPTY_RECORD";
5564        case RIL_E_INVALID_SMS_FORMAT: return "E_INVALID_SMS_FORMAT";
5565        case RIL_E_ENCODING_ERR: return "E_ENCODING_ERR";
5566        case RIL_E_INVALID_SMSC_ADDRESS: return "E_INVALID_SMSC_ADDRESS";
5567        case RIL_E_NO_SUCH_ENTRY: return "E_NO_SUCH_ENTRY";
5568        case RIL_E_NETWORK_NOT_READY: return "E_NETWORK_NOT_READY";
5569        case RIL_E_NOT_PROVISIONED: return "E_NOT_PROVISIONED";
5570        case RIL_E_NO_SUBSCRIPTION: return "E_NO_SUBSCRIPTION";
5571        case RIL_E_NO_NETWORK_FOUND: return "E_NO_NETWORK_FOUND";
5572        case RIL_E_DEVICE_IN_USE: return "E_DEVICE_IN_USE";
5573        case RIL_E_ABORTED: return "E_ABORTED";
5574        case RIL_E_OEM_ERROR_1: return "E_OEM_ERROR_1";
5575        case RIL_E_OEM_ERROR_2: return "E_OEM_ERROR_2";
5576        case RIL_E_OEM_ERROR_3: return "E_OEM_ERROR_3";
5577        case RIL_E_OEM_ERROR_4: return "E_OEM_ERROR_4";
5578        case RIL_E_OEM_ERROR_5: return "E_OEM_ERROR_5";
5579        case RIL_E_OEM_ERROR_6: return "E_OEM_ERROR_6";
5580        case RIL_E_OEM_ERROR_7: return "E_OEM_ERROR_7";
5581        case RIL_E_OEM_ERROR_8: return "E_OEM_ERROR_8";
5582        case RIL_E_OEM_ERROR_9: return "E_OEM_ERROR_9";
5583        case RIL_E_OEM_ERROR_10: return "E_OEM_ERROR_10";
5584        case RIL_E_OEM_ERROR_11: return "E_OEM_ERROR_11";
5585        case RIL_E_OEM_ERROR_12: return "E_OEM_ERROR_12";
5586        case RIL_E_OEM_ERROR_13: return "E_OEM_ERROR_13";
5587        case RIL_E_OEM_ERROR_14: return "E_OEM_ERROR_14";
5588        case RIL_E_OEM_ERROR_15: return "E_OEM_ERROR_15";
5589        case RIL_E_OEM_ERROR_16: return "E_OEM_ERROR_16";
5590        case RIL_E_OEM_ERROR_17: return "E_OEM_ERROR_17";
5591        case RIL_E_OEM_ERROR_18: return "E_OEM_ERROR_18";
5592        case RIL_E_OEM_ERROR_19: return "E_OEM_ERROR_19";
5593        case RIL_E_OEM_ERROR_20: return "E_OEM_ERROR_20";
5594        case RIL_E_OEM_ERROR_21: return "E_OEM_ERROR_21";
5595        case RIL_E_OEM_ERROR_22: return "E_OEM_ERROR_22";
5596        case RIL_E_OEM_ERROR_23: return "E_OEM_ERROR_23";
5597        case RIL_E_OEM_ERROR_24: return "E_OEM_ERROR_24";
5598        case RIL_E_OEM_ERROR_25: return "E_OEM_ERROR_25";
5599        default: return "<unknown error>";
5600    }
5601}
5602
5603const char *
5604radioStateToString(RIL_RadioState s) {
5605    switch(s) {
5606        case RADIO_STATE_OFF: return "RADIO_OFF";
5607        case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE";
5608        case RADIO_STATE_SIM_NOT_READY: return "RADIO_SIM_NOT_READY";
5609        case RADIO_STATE_SIM_LOCKED_OR_ABSENT: return "RADIO_SIM_LOCKED_OR_ABSENT";
5610        case RADIO_STATE_SIM_READY: return "RADIO_SIM_READY";
5611        case RADIO_STATE_RUIM_NOT_READY:return"RADIO_RUIM_NOT_READY";
5612        case RADIO_STATE_RUIM_READY:return"RADIO_RUIM_READY";
5613        case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:return"RADIO_RUIM_LOCKED_OR_ABSENT";
5614        case RADIO_STATE_NV_NOT_READY:return"RADIO_NV_NOT_READY";
5615        case RADIO_STATE_NV_READY:return"RADIO_NV_READY";
5616        case RADIO_STATE_ON:return"RADIO_ON";
5617        default: return "<unknown state>";
5618    }
5619}
5620
5621const char *
5622callStateToString(RIL_CallState s) {
5623    switch(s) {
5624        case RIL_CALL_ACTIVE : return "ACTIVE";
5625        case RIL_CALL_HOLDING: return "HOLDING";
5626        case RIL_CALL_DIALING: return "DIALING";
5627        case RIL_CALL_ALERTING: return "ALERTING";
5628        case RIL_CALL_INCOMING: return "INCOMING";
5629        case RIL_CALL_WAITING: return "WAITING";
5630        default: return "<unknown state>";
5631    }
5632}
5633
5634const char *
5635requestToString(int request) {
5636/*
5637 cat libs/telephony/ril_commands.h \
5638 | egrep "^ *{RIL_" \
5639 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
5640
5641
5642 cat libs/telephony/ril_unsol_commands.h \
5643 | egrep "^ *{RIL_" \
5644 | sed -re 's/\{RIL_([^,]+),([^}]+).+/case RIL_\1: return "\1";/'
5645
5646*/
5647    switch(request) {
5648        case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
5649        case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
5650        case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
5651        case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
5652        case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
5653        case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
5654        case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
5655        case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
5656        case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
5657        case RIL_REQUEST_DIAL: return "DIAL";
5658        case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
5659        case RIL_REQUEST_HANGUP: return "HANGUP";
5660        case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
5661        case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
5662        case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
5663        case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
5664        case RIL_REQUEST_UDUB: return "UDUB";
5665        case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
5666        case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
5667        case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
5668        case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
5669        case RIL_REQUEST_OPERATOR: return "OPERATOR";
5670        case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
5671        case RIL_REQUEST_DTMF: return "DTMF";
5672        case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
5673        case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
5674        case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
5675        case RIL_REQUEST_SIM_IO: return "SIM_IO";
5676        case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
5677        case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
5678        case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
5679        case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
5680        case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
5681        case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
5682        case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
5683        case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
5684        case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
5685        case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
5686        case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
5687        case RIL_REQUEST_ANSWER: return "ANSWER";
5688        case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
5689        case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
5690        case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
5691        case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
5692        case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
5693        case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
5694        case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
5695        case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
5696        case RIL_REQUEST_DTMF_START: return "DTMF_START";
5697        case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
5698        case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
5699        case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
5700        case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE";
5701        case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE";
5702        case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS";
5703        case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
5704        case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
5705        case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
5706        case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
5707        case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
5708        case RIL_REQUEST_NV_RESET_CONFIG: return "NV_RESET_CONFIG";
5709        case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
5710        case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
5711        case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
5712        case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
5713        case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
5714        case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE";
5715        case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE";
5716        case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND";
5717        case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE";
5718        case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
5719        case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
5720        case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER";
5721        case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES";
5722        case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:return"CDMA_SET_SUBSCRIPTION_SOURCE";
5723        case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:return"CDMA_SET_ROAMING_PREFERENCE";
5724        case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:return"CDMA_QUERY_ROAMING_PREFERENCE";
5725        case RIL_REQUEST_SET_TTY_MODE:return"SET_TTY_MODE";
5726        case RIL_REQUEST_QUERY_TTY_MODE:return"QUERY_TTY_MODE";
5727        case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
5728        case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
5729        case RIL_REQUEST_CDMA_FLASH:return"CDMA_FLASH";
5730        case RIL_REQUEST_CDMA_BURST_DTMF:return"CDMA_BURST_DTMF";
5731        case RIL_REQUEST_CDMA_SEND_SMS:return"CDMA_SEND_SMS";
5732        case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:return"CDMA_SMS_ACKNOWLEDGE";
5733        case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG:return"GSM_GET_BROADCAST_SMS_CONFIG";
5734        case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG:return"GSM_SET_BROADCAST_SMS_CONFIG";
5735        case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG:return "CDMA_GET_BROADCAST_SMS_CONFIG";
5736        case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG:return "CDMA_SET_BROADCAST_SMS_CONFIG";
5737        case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION:return "CDMA_SMS_BROADCAST_ACTIVATION";
5738        case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return"CDMA_VALIDATE_AND_WRITE_AKEY";
5739        case RIL_REQUEST_CDMA_SUBSCRIPTION: return"CDMA_SUBSCRIPTION";
5740        case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "CDMA_WRITE_SMS_TO_RUIM";
5741        case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "CDMA_DELETE_SMS_ON_RUIM";
5742        case RIL_REQUEST_DEVICE_IDENTITY: return "DEVICE_IDENTITY";
5743        case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "EXIT_EMERGENCY_CALLBACK_MODE";
5744        case RIL_REQUEST_GET_SMSC_ADDRESS: return "GET_SMSC_ADDRESS";
5745        case RIL_REQUEST_SET_SMSC_ADDRESS: return "SET_SMSC_ADDRESS";
5746        case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "REPORT_SMS_MEMORY_STATUS";
5747        case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "REPORT_STK_SERVICE_IS_RUNNING";
5748        case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "CDMA_GET_SUBSCRIPTION_SOURCE";
5749        case RIL_REQUEST_ISIM_AUTHENTICATION: return "ISIM_AUTHENTICATION";
5750        case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
5751        case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
5752        case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH";
5753        case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM";
5754        case RIL_REQUEST_GET_CELL_INFO_LIST: return"GET_CELL_INFO_LIST";
5755        case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return"SET_UNSOL_CELL_INFO_LIST_RATE";
5756        case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "RIL_REQUEST_SET_INITIAL_ATTACH_APN";
5757        case RIL_REQUEST_IMS_REGISTRATION_STATE: return "IMS_REGISTRATION_STATE";
5758        case RIL_REQUEST_IMS_SEND_SMS: return "IMS_SEND_SMS";
5759        case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC: return "SIM_TRANSMIT_APDU_BASIC";
5760        case RIL_REQUEST_SIM_OPEN_CHANNEL: return "SIM_OPEN_CHANNEL";
5761        case RIL_REQUEST_SIM_CLOSE_CHANNEL: return "SIM_CLOSE_CHANNEL";
5762        case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL: return "SIM_TRANSMIT_APDU_CHANNEL";
5763        case RIL_REQUEST_GET_RADIO_CAPABILITY: return "RIL_REQUEST_GET_RADIO_CAPABILITY";
5764        case RIL_REQUEST_SET_RADIO_CAPABILITY: return "RIL_REQUEST_SET_RADIO_CAPABILITY";
5765        case RIL_REQUEST_SET_UICC_SUBSCRIPTION: return "SET_UICC_SUBSCRIPTION";
5766        case RIL_REQUEST_ALLOW_DATA: return "ALLOW_DATA";
5767        case RIL_REQUEST_GET_HARDWARE_CONFIG: return "GET_HARDWARE_CONFIG";
5768        case RIL_REQUEST_SIM_AUTHENTICATION: return "SIM_AUTHENTICATION";
5769        case RIL_REQUEST_GET_DC_RT_INFO: return "GET_DC_RT_INFO";
5770        case RIL_REQUEST_SET_DC_RT_INFO_RATE: return "SET_DC_RT_INFO_RATE";
5771        case RIL_REQUEST_SET_DATA_PROFILE: return "SET_DATA_PROFILE";
5772        case RIL_REQUEST_SET_CARRIER_RESTRICTIONS: return "SET_CARRIER_RESTRICTIONS";
5773        case RIL_REQUEST_GET_CARRIER_RESTRICTIONS: return "GET_CARRIER_RESTRICTIONS";
5774        case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
5775        case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
5776        case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
5777        case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
5778        case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
5779        case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
5780        case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
5781        case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
5782        case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
5783        case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
5784        case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION";
5785        case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
5786        case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
5787        case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
5788        case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
5789        case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FUL";
5790        case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
5791        case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
5792        case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
5793        case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
5794        case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_NEW_CDMA_SMS";
5795        case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_NEW_BROADCAST_SMS";
5796        case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
5797        case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
5798        case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
5799        case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
5800        case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
5801        case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
5802        case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
5803        case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONE";
5804        case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
5805        case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED";
5806        case RIL_UNSOL_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
5807        case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
5808        case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
5809        case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED";
5810        case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST";
5811        case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return "RESPONSE_IMS_NETWORK_STATE_CHANGED";
5812        case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED: return "UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED";
5813        case RIL_UNSOL_SRVCC_STATE_NOTIFY: return "UNSOL_SRVCC_STATE_NOTIFY";
5814        case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: return "HARDWARE_CONFIG_CHANGED";
5815        case RIL_UNSOL_DC_RT_INFO_CHANGED: return "UNSOL_DC_RT_INFO_CHANGED";
5816        case RIL_REQUEST_SHUTDOWN: return "SHUTDOWN";
5817        case RIL_UNSOL_RADIO_CAPABILITY: return "RIL_UNSOL_RADIO_CAPABILITY";
5818        case RIL_RESPONSE_ACKNOWLEDGEMENT: return "RIL_RESPONSE_ACKNOWLEDGEMENT";
5819        case RIL_UNSOL_PCO_DATA: return "RIL_UNSOL_PCO_DATA";
5820        default: return "<unknown request>";
5821    }
5822}
5823
5824const char *
5825rilSocketIdToString(RIL_SOCKET_ID socket_id)
5826{
5827    switch(socket_id) {
5828        case RIL_SOCKET_1:
5829            return "RIL_SOCKET_1";
5830#if (SIM_COUNT >= 2)
5831        case RIL_SOCKET_2:
5832            return "RIL_SOCKET_2";
5833#endif
5834#if (SIM_COUNT >= 3)
5835        case RIL_SOCKET_3:
5836            return "RIL_SOCKET_3";
5837#endif
5838#if (SIM_COUNT >= 4)
5839        case RIL_SOCKET_4:
5840            return "RIL_SOCKET_4";
5841#endif
5842        default:
5843            return "not a valid RIL";
5844    }
5845}
5846
5847/*
5848 * Returns true for a debuggable build.
5849 */
5850static bool isDebuggable() {
5851    char debuggable[PROP_VALUE_MAX];
5852    property_get("ro.debuggable", debuggable, "0");
5853    if (strcmp(debuggable, "1") == 0) {
5854        return true;
5855    }
5856    return false;
5857}
5858
5859} /* namespace android */
5860
5861void rilEventAddWakeup_helper(struct ril_event *ev) {
5862    android::rilEventAddWakeup(ev);
5863}
5864
5865void listenCallback_helper(int fd, short flags, void *param) {
5866    android::listenCallback(fd, flags, param);
5867}
5868
5869int blockingWrite_helper(int fd, void *buffer, size_t len) {
5870    return android::blockingWrite(fd, buffer, len);
5871}
5872