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