blob: 98779cc1a45691863d100d21a87644557c1e132c [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
117enum WakeType {DONT_WAKE, WAKE_PARTIAL};
118
119typedef struct {
120 int requestNumber;
121 void (*dispatchFunction) (Parcel &p, struct RequestInfo *pRI);
122 int(*responseFunction) (Parcel &p, void *response, size_t responselen);
123} CommandInfo;
124
125typedef struct {
126 int requestNumber;
127 int (*responseFunction) (Parcel &p, void *response, size_t responselen);
128 WakeType wakeType;
129} UnsolResponseInfo;
130
131typedef struct RequestInfo {
132 int32_t token; //this is not RIL_Token
133 CommandInfo *pCI;
134 struct RequestInfo *p_next;
135 char cancelled;
136 char local; // responses to local commands do not go back to command process
137} RequestInfo;
138
139typedef struct UserCallbackInfo {
140 RIL_TimedCallback p_callback;
141 void *userParam;
142 struct ril_event event;
143 struct UserCallbackInfo *p_next;
144} UserCallbackInfo;
145
146
147/*******************************************************************/
148
149RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL};
150static int s_registerCalled = 0;
151
152static pthread_t s_tid_dispatch;
153static pthread_t s_tid_reader;
154static int s_started = 0;
155
156static int s_fdListen = -1;
157static int s_fdCommand = -1;
158static int s_fdDebug = -1;
159
160static int s_fdWakeupRead;
161static int s_fdWakeupWrite;
162
163static struct ril_event s_commands_event;
164static struct ril_event s_wakeupfd_event;
165static struct ril_event s_listen_event;
166static struct ril_event s_wake_timeout_event;
167static struct ril_event s_debug_event;
168
169
170static const struct timeval TIMEVAL_WAKE_TIMEOUT = {1,0};
171
172static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER;
173static pthread_mutex_t s_writeMutex = PTHREAD_MUTEX_INITIALIZER;
174static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
175static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER;
176
177static pthread_mutex_t s_dispatchMutex = PTHREAD_MUTEX_INITIALIZER;
178static pthread_cond_t s_dispatchCond = PTHREAD_COND_INITIALIZER;
179
180static RequestInfo *s_pendingRequests = NULL;
181
182static RequestInfo *s_toDispatchHead = NULL;
183static RequestInfo *s_toDispatchTail = NULL;
184
185static UserCallbackInfo *s_last_wake_timeout_info = NULL;
186
187static void *s_lastNITZTimeData = NULL;
188static size_t s_lastNITZTimeDataSize;
189
190#if RILC_LOG
191 static char printBuf[PRINTBUF_SIZE];
192#endif
193
194/*******************************************************************/
195
196static void dispatchVoid (Parcel& p, RequestInfo *pRI);
197static void dispatchString (Parcel& p, RequestInfo *pRI);
198static void dispatchStrings (Parcel& p, RequestInfo *pRI);
199static void dispatchInts (Parcel& p, RequestInfo *pRI);
200static void dispatchDial (Parcel& p, RequestInfo *pRI);
201static void dispatchSIM_IO (Parcel& p, RequestInfo *pRI);
202static void dispatchCallForward(Parcel& p, RequestInfo *pRI);
203static void dispatchRaw(Parcel& p, RequestInfo *pRI);
204static void dispatchSmsWrite (Parcel &p, RequestInfo *pRI);
205static void dispatchDataCall (Parcel& p, RequestInfo *pRI);
206static void dispatchVoiceRadioTech (Parcel& p, RequestInfo *pRI);
207static void dispatchCdmaSubscriptionSource (Parcel& p, RequestInfo *pRI);
208
209static void dispatchCdmaSms(Parcel &p, RequestInfo *pRI);
210static void dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI);
211static void dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI);
212static void dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI);
213static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI);
214static int responseInts(Parcel &p, void *response, size_t responselen);
215static int responseIntsGetPreferredNetworkType(Parcel &p, void *response, size_t responselen);
216static int responseStrings(Parcel &p, void *response, size_t responselen);
217static int responseStringsNetworks(Parcel &p, void *response, size_t responselen);
218static int responseStrings(Parcel &p, void *response, size_t responselen, bool network_search);
219static int responseString(Parcel &p, void *response, size_t responselen);
220static int responseVoid(Parcel &p, void *response, size_t responselen);
221static int responseCallList(Parcel &p, void *response, size_t responselen);
222static int responseSMS(Parcel &p, void *response, size_t responselen);
223static int responseSIM_IO(Parcel &p, void *response, size_t responselen);
224static int responseCallForwards(Parcel &p, void *response, size_t responselen);
225static int responseDataCallList(Parcel &p, void *response, size_t responselen);
226static int responseSetupDataCall(Parcel &p, void *response, size_t responselen);
227static int responseRaw(Parcel &p, void *response, size_t responselen);
228static int responseSsn(Parcel &p, void *response, size_t responselen);
229static int responseSimStatus(Parcel &p, void *response, size_t responselen);
230static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen);
231static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen);
232static int responseCdmaSms(Parcel &p, void *response, size_t responselen);
233static int responseCellList(Parcel &p, void *response, size_t responselen);
234static int responseCdmaInformationRecords(Parcel &p,void *response, size_t responselen);
235static int responseRilSignalStrength(Parcel &p,void *response, size_t responselen);
236static int responseCallRing(Parcel &p, void *response, size_t responselen);
237static int responseCdmaSignalInfoRecord(Parcel &p,void *response, size_t responselen);
238static int responseCdmaCallWaiting(Parcel &p,void *response, size_t responselen);
239static int responseSimRefresh(Parcel &p, void *response, size_t responselen);
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200240static int responseCellInfoList(Parcel &p, void *response, size_t responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200241
242static int decodeVoiceRadioTechnology (RIL_RadioState radioState);
243static int decodeCdmaSubscriptionSource (RIL_RadioState radioState);
244static RIL_RadioState processRadioState(RIL_RadioState newRadioState);
245
246extern "C" const char * requestToString(int request);
247extern "C" const char * failCauseToString(RIL_Errno);
248extern "C" const char * callStateToString(RIL_CallState);
249extern "C" const char * radioStateToString(RIL_RadioState);
250
251#ifdef RIL_SHLIB
252extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, void *data,
253 size_t datalen);
254#endif
255
256static UserCallbackInfo * internalRequestTimedCallback
257 (RIL_TimedCallback callback, void *param,
258 const struct timeval *relativeTime);
259
260/** Index == requestNumber */
261static CommandInfo s_commands[] = {
262#include "ril_commands.h"
263};
264
265static UnsolResponseInfo s_unsolResponses[] = {
266#include "ril_unsol_commands.h"
267};
268
269/* For older RILs that do not support new commands RIL_REQUEST_VOICE_RADIO_TECH and
270 RIL_UNSOL_VOICE_RADIO_TECH_CHANGED messages, decode the voice radio tech from
271 radio state message and store it. Every time there is a change in Radio State
272 check to see if voice radio tech changes and notify telephony
273 */
274int voiceRadioTech = -1;
275
276/* For older RILs that do not support new commands RIL_REQUEST_GET_CDMA_SUBSCRIPTION_SOURCE
277 and RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED messages, decode the subscription
278 source from radio state and store it. Every time there is a change in Radio State
279 check to see if subscription source changed and notify telephony
280 */
281int cdmaSubscriptionSource = -1;
282
283/* For older RILs that do not send RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, decode the
284 SIM/RUIM state from radio state and store it. Every time there is a change in Radio State,
285 check to see if SIM/RUIM status changed and notify telephony
286 */
287int simRuimStatus = -1;
288
289static char *
290strdupReadString(Parcel &p) {
291 size_t stringlen;
292 const char16_t *s16;
293
294 s16 = p.readString16Inplace(&stringlen);
295
296 return strndup16to8(s16, stringlen);
297}
298
299static void writeStringToParcel(Parcel &p, const char *s) {
300 char16_t *s16;
301 size_t s16_len;
302 s16 = strdup8to16(s, &s16_len);
303 p.writeString16(s16, s16_len);
304 free(s16);
305}
306
307
308static void
309memsetString (char *s) {
310 if (s != NULL) {
311 memset (s, 0, strlen(s));
312 }
313}
314
315void nullParcelReleaseFunction (const uint8_t* data, size_t dataSize,
316 const size_t* objects, size_t objectsSize,
317 void* cookie) {
318 // do nothing -- the data reference lives longer than the Parcel object
319}
320
321/**
322 * To be called from dispatch thread
323 * Issue a single local request, ensuring that the response
324 * is not sent back up to the command process
325 */
326static void
327issueLocalRequest(int request, void *data, int len) {
328 RequestInfo *pRI;
329 int index;
330 int ret;
331
332 pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
333
334 pRI->local = 1;
335 pRI->token = 0xffffffff; // token is not used in this context
336
337 /* Hack to include Samsung requests */
338 if (request > 10000) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200339 index = request - 10000 + RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE;
Ethan Chend6e30652013-08-04 22:49:56 -0700340 RLOGD("SAMSUNG: request=%d, index=%d", request, index);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200341 pRI->pCI = &(s_commands[index]);
342 } else {
343 pRI->pCI = &(s_commands[request]);
344 }
345
346 ret = pthread_mutex_lock(&s_pendingRequestsMutex);
347 assert (ret == 0);
348
349 pRI->p_next = s_pendingRequests;
350 s_pendingRequests = pRI;
351
352 ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
353 assert (ret == 0);
354
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200355 RLOGD("C[locl]> %s", requestToString(request));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200356
357 s_callbacks.onRequest(request, data, len, pRI);
358}
359
360static int
361processCommandBuffer(void *buffer, size_t buflen) {
362 Parcel p;
363 status_t status;
364 int32_t request;
365 int32_t token;
366 RequestInfo *pRI;
367 int index;
368 int ret;
369
370 p.setData((uint8_t *) buffer, buflen);
371
372 // status checked at end
373 status = p.readInt32(&request);
374 status = p.readInt32 (&token);
375
376 if (status != NO_ERROR) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200377 RLOGE("invalid request block");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200378 return 0;
379 }
380
381 /* Hack to include Samsung requests */
Ethan Chend6e30652013-08-04 22:49:56 -0700382 if (request < 1 || ((request > RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE) &&
383 (request < RIL_REQUEST_GET_CELL_BROADCAST_CONFIG)) ||
384 request > RIL_REQUEST_HANGUP_VT) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200385 RLOGE("unsupported request code %d token %d", request, token);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200386 // FIXME this should perhaps return a response
387 return 0;
388 }
389
390 pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
391
392 pRI->token = token;
393
394 /* Hack to include Samsung requests */
395 if (request > 10000) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200396 index = request - 10000 + RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE;
Ethan Chend6e30652013-08-04 22:49:56 -0700397 RLOGD("processCommandBuffer: samsung request=%d, index=%d",
398 request, index);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200399 pRI->pCI = &(s_commands[index]);
400 } else {
401 pRI->pCI = &(s_commands[request]);
402 }
403
404 ret = pthread_mutex_lock(&s_pendingRequestsMutex);
405 assert (ret == 0);
406
407 pRI->p_next = s_pendingRequests;
408 s_pendingRequests = pRI;
409
410 ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
411 assert (ret == 0);
412
413/* sLastDispatchedToken = token; */
414
415 pRI->pCI->dispatchFunction(p, pRI);
416
417 return 0;
418}
419
420static void
421invalidCommandBlock (RequestInfo *pRI) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200422 RLOGE("invalid command block for token %d request %s",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200423 pRI->token, requestToString(pRI->pCI->requestNumber));
424}
425
426/** Callee expects NULL */
427static void
428dispatchVoid (Parcel& p, RequestInfo *pRI) {
429 clearPrintBuf;
430 printRequest(pRI->token, pRI->pCI->requestNumber);
431 s_callbacks.onRequest(pRI->pCI->requestNumber, NULL, 0, pRI);
432}
433
434/** Callee expects const char * */
435static void
436dispatchString (Parcel& p, RequestInfo *pRI) {
437 status_t status;
438 size_t datalen;
439 size_t stringlen;
440 char *string8 = NULL;
441
442 string8 = strdupReadString(p);
443
444 startRequest;
445 appendPrintBuf("%s%s", printBuf, string8);
446 closeRequest;
447 printRequest(pRI->token, pRI->pCI->requestNumber);
448
449 s_callbacks.onRequest(pRI->pCI->requestNumber, string8,
450 sizeof(char *), pRI);
451
452#ifdef MEMSET_FREED
453 memsetString(string8);
454#endif
455
456 free(string8);
457 return;
458invalid:
459 invalidCommandBlock(pRI);
460 return;
461}
462
463/** Callee expects const char ** */
464static void
465dispatchStrings (Parcel &p, RequestInfo *pRI) {
466 int32_t countStrings;
467 status_t status;
468 size_t datalen;
469 char **pStrings;
470
471 status = p.readInt32 (&countStrings);
472
473 if (status != NO_ERROR) {
474 goto invalid;
475 }
476
477 startRequest;
478 if (countStrings == 0) {
479 // just some non-null pointer
480 pStrings = (char **)alloca(sizeof(char *));
481 datalen = 0;
482 } else if (((int)countStrings) == -1) {
483 pStrings = NULL;
484 datalen = 0;
485 } else {
486 datalen = sizeof(char *) * countStrings;
487
488 pStrings = (char **)alloca(datalen);
489
490 for (int i = 0 ; i < countStrings ; i++) {
491 pStrings[i] = strdupReadString(p);
492 appendPrintBuf("%s%s,", printBuf, pStrings[i]);
493 }
494 }
495 removeLastChar;
496 closeRequest;
497 printRequest(pRI->token, pRI->pCI->requestNumber);
498
499 s_callbacks.onRequest(pRI->pCI->requestNumber, pStrings, datalen, pRI);
500
501 if (pStrings != NULL) {
502 for (int i = 0 ; i < countStrings ; i++) {
503#ifdef MEMSET_FREED
504 memsetString (pStrings[i]);
505#endif
506 free(pStrings[i]);
507 }
508
509#ifdef MEMSET_FREED
510 memset(pStrings, 0, datalen);
511#endif
512 }
513
514 return;
515invalid:
516 invalidCommandBlock(pRI);
517 return;
518}
519
520/** Callee expects const int * */
521static void
522dispatchInts (Parcel &p, RequestInfo *pRI) {
523 int32_t count;
524 status_t status;
525 size_t datalen;
526 int *pInts;
527
528 status = p.readInt32 (&count);
529
530 if (status != NO_ERROR || count == 0) {
531 goto invalid;
532 }
533
534 datalen = sizeof(int) * count;
535 pInts = (int *)alloca(datalen);
536
537 startRequest;
538 for (int i = 0 ; i < count ; i++) {
539 int32_t t;
540
541 status = p.readInt32(&t);
542 pInts[i] = (int)t;
543 appendPrintBuf("%s%d,", printBuf, t);
544
545 if (status != NO_ERROR) {
546 goto invalid;
547 }
548 }
549 removeLastChar;
550 closeRequest;
551 printRequest(pRI->token, pRI->pCI->requestNumber);
552
553 s_callbacks.onRequest(pRI->pCI->requestNumber, const_cast<int *>(pInts),
554 datalen, pRI);
555
556#ifdef MEMSET_FREED
557 memset(pInts, 0, datalen);
558#endif
559
560 return;
561invalid:
562 invalidCommandBlock(pRI);
563 return;
564}
565
566
567/**
568 * Callee expects const RIL_SMS_WriteArgs *
569 * Payload is:
570 * int32_t status
571 * String pdu
572 */
573static void
574dispatchSmsWrite (Parcel &p, RequestInfo *pRI) {
575 RIL_SMS_WriteArgs args;
576 int32_t t;
577 status_t status;
578
579 memset (&args, 0, sizeof(args));
580
581 status = p.readInt32(&t);
582 args.status = (int)t;
583
584 args.pdu = strdupReadString(p);
585
586 if (status != NO_ERROR || args.pdu == NULL) {
587 goto invalid;
588 }
589
590 args.smsc = strdupReadString(p);
591
592 startRequest;
593 appendPrintBuf("%s%d,%s,smsc=%s", printBuf, args.status,
594 (char*)args.pdu, (char*)args.smsc);
595 closeRequest;
596 printRequest(pRI->token, pRI->pCI->requestNumber);
597
598 s_callbacks.onRequest(pRI->pCI->requestNumber, &args, sizeof(args), pRI);
599
600#ifdef MEMSET_FREED
601 memsetString (args.pdu);
602#endif
603
604 free (args.pdu);
605
606#ifdef MEMSET_FREED
607 memset(&args, 0, sizeof(args));
608#endif
609
610 return;
611invalid:
612 invalidCommandBlock(pRI);
613 return;
614}
615
616/**
617 * Callee expects const RIL_Dial *
618 * Payload is:
619 * String address
620 * int32_t clir
621 */
622static void
623dispatchDial (Parcel &p, RequestInfo *pRI) {
624 RIL_Dial dial;
625 RIL_UUS_Info uusInfo;
626 int32_t sizeOfDial;
627 int32_t t;
628 int32_t uusPresent;
629 status_t status;
630
631 memset (&dial, 0, sizeof(dial));
632
633 dial.address = strdupReadString(p);
634
635 status = p.readInt32(&t);
636 dial.clir = (int)t;
637
638 if (status != NO_ERROR || dial.address == NULL) {
639 goto invalid;
640 }
641
642 if (s_callbacks.version < 3) { // Remove when partners upgrade to version 3
643 uusPresent = 0;
644 sizeOfDial = sizeof(dial) - sizeof(RIL_UUS_Info *);
645 } else {
646 status = p.readInt32(&uusPresent);
647
648 if (status != NO_ERROR) {
649 goto invalid;
650 }
651
652 if (uusPresent == 0) {
653 dial.uusInfo = NULL;
654 } else {
655 int32_t len;
656
657 memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
658
659 status = p.readInt32(&t);
660 uusInfo.uusType = (RIL_UUS_Type) t;
661
662 status = p.readInt32(&t);
663 uusInfo.uusDcs = (RIL_UUS_DCS) t;
664
665 status = p.readInt32(&len);
666 if (status != NO_ERROR) {
667 goto invalid;
668 }
669
670 // The java code writes -1 for null arrays
671 if (((int) len) == -1) {
672 uusInfo.uusData = NULL;
673 len = 0;
674 } else {
675 uusInfo.uusData = (char*) p.readInplace(len);
676 }
677
678 uusInfo.uusLength = len;
679 dial.uusInfo = &uusInfo;
680 }
681 sizeOfDial = sizeof(dial);
682 }
683
684 startRequest;
685 appendPrintBuf("%snum=%s,clir=%d", printBuf, dial.address, dial.clir);
686 if (uusPresent) {
687 appendPrintBuf("%s,uusType=%d,uusDcs=%d,uusLen=%d", printBuf,
688 dial.uusInfo->uusType, dial.uusInfo->uusDcs,
689 dial.uusInfo->uusLength);
690 }
691 closeRequest;
692 printRequest(pRI->token, pRI->pCI->requestNumber);
693
694 s_callbacks.onRequest(pRI->pCI->requestNumber, &dial, sizeOfDial, pRI);
695
696#ifdef MEMSET_FREED
697 memsetString (dial.address);
698#endif
699
700 free (dial.address);
701
702#ifdef MEMSET_FREED
703 memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
704 memset(&dial, 0, sizeof(dial));
705#endif
706
707 return;
708invalid:
709 invalidCommandBlock(pRI);
710 return;
711}
712
713/**
714 * Callee expects const RIL_SIM_IO *
715 * Payload is:
716 * int32_t command
717 * int32_t fileid
718 * String path
719 * int32_t p1, p2, p3
720 * String data
721 * String pin2
722 * String aidPtr
723 */
724static void
725dispatchSIM_IO (Parcel &p, RequestInfo *pRI) {
726 union RIL_SIM_IO {
727 RIL_SIM_IO_v6 v6;
728 RIL_SIM_IO_v5 v5;
729 } simIO;
730
731 int32_t t;
732 int size;
733 status_t status;
734
735 memset (&simIO, 0, sizeof(simIO));
736
737 // note we only check status at the end
738
739 status = p.readInt32(&t);
740 simIO.v6.command = (int)t;
741
742 status = p.readInt32(&t);
743 simIO.v6.fileid = (int)t;
744
745 simIO.v6.path = strdupReadString(p);
746
747 status = p.readInt32(&t);
748 simIO.v6.p1 = (int)t;
749
750 status = p.readInt32(&t);
751 simIO.v6.p2 = (int)t;
752
753 status = p.readInt32(&t);
754 simIO.v6.p3 = (int)t;
755
756 simIO.v6.data = strdupReadString(p);
757 simIO.v6.pin2 = strdupReadString(p);
758 simIO.v6.aidPtr = strdupReadString(p);
759
760 startRequest;
761 appendPrintBuf("%scmd=0x%X,efid=0x%X,path=%s,%d,%d,%d,%s,pin2=%s,aid=%s", printBuf,
762 simIO.v6.command, simIO.v6.fileid, (char*)simIO.v6.path,
763 simIO.v6.p1, simIO.v6.p2, simIO.v6.p3,
764 (char*)simIO.v6.data, (char*)simIO.v6.pin2, simIO.v6.aidPtr);
765 closeRequest;
766 printRequest(pRI->token, pRI->pCI->requestNumber);
767
768 if (status != NO_ERROR) {
769 goto invalid;
770 }
771
772 size = (s_callbacks.version < 6) ? sizeof(simIO.v5) : sizeof(simIO.v6);
773 s_callbacks.onRequest(pRI->pCI->requestNumber, &simIO, size, pRI);
774
775#ifdef MEMSET_FREED
776 memsetString (simIO.v6.path);
777 memsetString (simIO.v6.data);
778 memsetString (simIO.v6.pin2);
779 memsetString (simIO.v6.aidPtr);
780#endif
781
782 free (simIO.v6.path);
783 free (simIO.v6.data);
784 free (simIO.v6.pin2);
785 free (simIO.v6.aidPtr);
786
787#ifdef MEMSET_FREED
788 memset(&simIO, 0, sizeof(simIO));
789#endif
790
791 return;
792invalid:
793 invalidCommandBlock(pRI);
794 return;
795}
796
797/**
798 * Callee expects const RIL_CallForwardInfo *
799 * Payload is:
800 * int32_t status/action
801 * int32_t reason
802 * int32_t serviceCode
803 * int32_t toa
804 * String number (0 length -> null)
805 * int32_t timeSeconds
806 */
807static void
808dispatchCallForward(Parcel &p, RequestInfo *pRI) {
809 RIL_CallForwardInfo cff;
810 int32_t t;
811 status_t status;
812
813 memset (&cff, 0, sizeof(cff));
814
815 // note we only check status at the end
816
817 status = p.readInt32(&t);
818 cff.status = (int)t;
819
820 status = p.readInt32(&t);
821 cff.reason = (int)t;
822
823 status = p.readInt32(&t);
824 cff.serviceClass = (int)t;
825
826 status = p.readInt32(&t);
827 cff.toa = (int)t;
828
829 cff.number = strdupReadString(p);
830
831 status = p.readInt32(&t);
832 cff.timeSeconds = (int)t;
833
834 if (status != NO_ERROR) {
835 goto invalid;
836 }
837
838 // special case: number 0-length fields is null
839
840 if (cff.number != NULL && strlen (cff.number) == 0) {
841 cff.number = NULL;
842 }
843
844 startRequest;
845 appendPrintBuf("%sstat=%d,reason=%d,serv=%d,toa=%d,%s,tout=%d", printBuf,
846 cff.status, cff.reason, cff.serviceClass, cff.toa,
847 (char*)cff.number, cff.timeSeconds);
848 closeRequest;
849 printRequest(pRI->token, pRI->pCI->requestNumber);
850
851 s_callbacks.onRequest(pRI->pCI->requestNumber, &cff, sizeof(cff), pRI);
852
853#ifdef MEMSET_FREED
854 memsetString(cff.number);
855#endif
856
857 free (cff.number);
858
859#ifdef MEMSET_FREED
860 memset(&cff, 0, sizeof(cff));
861#endif
862
863 return;
864invalid:
865 invalidCommandBlock(pRI);
866 return;
867}
868
869
870static void
871dispatchRaw(Parcel &p, RequestInfo *pRI) {
872 int32_t len;
873 status_t status;
874 const void *data;
875
876 status = p.readInt32(&len);
877
878 if (status != NO_ERROR) {
879 goto invalid;
880 }
881
882 // The java code writes -1 for null arrays
883 if (((int)len) == -1) {
884 data = NULL;
885 len = 0;
886 }
887
888 data = p.readInplace(len);
889
890 startRequest;
891 appendPrintBuf("%sraw_size=%d", printBuf, len);
892 closeRequest;
893 printRequest(pRI->token, pRI->pCI->requestNumber);
894
895 s_callbacks.onRequest(pRI->pCI->requestNumber, const_cast<void *>(data), len, pRI);
896
897 return;
898invalid:
899 invalidCommandBlock(pRI);
900 return;
901}
902
903static void
904dispatchCdmaSms(Parcel &p, RequestInfo *pRI) {
905 RIL_CDMA_SMS_Message rcsm;
906 int32_t t;
907 uint8_t ut;
908 status_t status;
909 int32_t digitCount;
910 int digitLimit;
911
912 memset(&rcsm, 0, sizeof(rcsm));
913
914 status = p.readInt32(&t);
915 rcsm.uTeleserviceID = (int) t;
916
917 status = p.read(&ut,sizeof(ut));
918 rcsm.bIsServicePresent = (uint8_t) ut;
919
920 status = p.readInt32(&t);
921 rcsm.uServicecategory = (int) t;
922
923 status = p.readInt32(&t);
924 rcsm.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
925
926 status = p.readInt32(&t);
927 rcsm.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
928
929 status = p.readInt32(&t);
930 rcsm.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
931
932 status = p.readInt32(&t);
933 rcsm.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
934
935 status = p.read(&ut,sizeof(ut));
936 rcsm.sAddress.number_of_digits= (uint8_t) ut;
937
938 digitLimit= MIN((rcsm.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
939 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
940 status = p.read(&ut,sizeof(ut));
941 rcsm.sAddress.digits[digitCount] = (uint8_t) ut;
942 }
943
944 status = p.readInt32(&t);
945 rcsm.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
946
947 status = p.read(&ut,sizeof(ut));
948 rcsm.sSubAddress.odd = (uint8_t) ut;
949
950 status = p.read(&ut,sizeof(ut));
951 rcsm.sSubAddress.number_of_digits = (uint8_t) ut;
952
953 digitLimit= MIN((rcsm.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
954 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
955 status = p.read(&ut,sizeof(ut));
956 rcsm.sSubAddress.digits[digitCount] = (uint8_t) ut;
957 }
958
959 status = p.readInt32(&t);
960 rcsm.uBearerDataLen = (int) t;
961
962 digitLimit= MIN((rcsm.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
963 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
964 status = p.read(&ut, sizeof(ut));
965 rcsm.aBearerData[digitCount] = (uint8_t) ut;
966 }
967
968 if (status != NO_ERROR) {
969 goto invalid;
970 }
971
972 startRequest;
973 appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
974 sAddress.digit_mode=%d, sAddress.Number_mode=%d, sAddress.number_type=%d, ",
975 printBuf, rcsm.uTeleserviceID,rcsm.bIsServicePresent,rcsm.uServicecategory,
976 rcsm.sAddress.digit_mode, rcsm.sAddress.number_mode,rcsm.sAddress.number_type);
977 closeRequest;
978
979 printRequest(pRI->token, pRI->pCI->requestNumber);
980
981 s_callbacks.onRequest(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm),pRI);
982
983#ifdef MEMSET_FREED
984 memset(&rcsm, 0, sizeof(rcsm));
985#endif
986
987 return;
988
989invalid:
990 invalidCommandBlock(pRI);
991 return;
992}
993
994static void
995dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI) {
996 RIL_CDMA_SMS_Ack rcsa;
997 int32_t t;
998 status_t status;
999 int32_t digitCount;
1000
1001 memset(&rcsa, 0, sizeof(rcsa));
1002
1003 status = p.readInt32(&t);
1004 rcsa.uErrorClass = (RIL_CDMA_SMS_ErrorClass) t;
1005
1006 status = p.readInt32(&t);
1007 rcsa.uSMSCauseCode = (int) t;
1008
1009 if (status != NO_ERROR) {
1010 goto invalid;
1011 }
1012
1013 startRequest;
1014 appendPrintBuf("%suErrorClass=%d, uTLStatus=%d, ",
1015 printBuf, rcsa.uErrorClass, rcsa.uSMSCauseCode);
1016 closeRequest;
1017
1018 printRequest(pRI->token, pRI->pCI->requestNumber);
1019
1020 s_callbacks.onRequest(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa),pRI);
1021
1022#ifdef MEMSET_FREED
1023 memset(&rcsa, 0, sizeof(rcsa));
1024#endif
1025
1026 return;
1027
1028invalid:
1029 invalidCommandBlock(pRI);
1030 return;
1031}
1032
1033static void
1034dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI) {
1035 int32_t t;
1036 status_t status;
1037 int32_t num;
1038
1039 status = p.readInt32(&num);
1040 if (status != NO_ERROR) {
1041 goto invalid;
1042 }
1043
Ethan Chend6e30652013-08-04 22:49:56 -07001044 {
1045 RIL_GSM_BroadcastSmsConfigInfo gsmBci[num];
1046 RIL_GSM_BroadcastSmsConfigInfo *gsmBciPtrs[num];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001047
Ethan Chend6e30652013-08-04 22:49:56 -07001048 startRequest;
1049 for (int i = 0 ; i < num ; i++ ) {
1050 gsmBciPtrs[i] = &gsmBci[i];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001051
Ethan Chend6e30652013-08-04 22:49:56 -07001052 status = p.readInt32(&t);
1053 gsmBci[i].fromServiceId = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001054
Ethan Chend6e30652013-08-04 22:49:56 -07001055 status = p.readInt32(&t);
1056 gsmBci[i].toServiceId = (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].fromCodeScheme = (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].toCodeScheme = (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].selected = (uint8_t) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001066
Ethan Chend6e30652013-08-04 22:49:56 -07001067 appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId =%d, \
1068 fromCodeScheme=%d, toCodeScheme=%d, selected =%d]", printBuf, i,
1069 gsmBci[i].fromServiceId, gsmBci[i].toServiceId,
1070 gsmBci[i].fromCodeScheme, gsmBci[i].toCodeScheme,
1071 gsmBci[i].selected);
1072 }
1073 closeRequest;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001074
Ethan Chend6e30652013-08-04 22:49:56 -07001075 if (status != NO_ERROR) {
1076 goto invalid;
1077 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001078
Ethan Chend6e30652013-08-04 22:49:56 -07001079 s_callbacks.onRequest(pRI->pCI->requestNumber,
1080 gsmBciPtrs,
1081 num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *),
1082 pRI);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001083
1084#ifdef MEMSET_FREED
Ethan Chend6e30652013-08-04 22:49:56 -07001085 memset(gsmBci, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo));
1086 memset(gsmBciPtrs, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001087#endif
Ethan Chend6e30652013-08-04 22:49:56 -07001088 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001089
1090 return;
1091
1092invalid:
1093 invalidCommandBlock(pRI);
1094 return;
1095}
1096
1097static void
1098dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI) {
1099 int32_t t;
1100 status_t status;
1101 int32_t num;
1102
1103 status = p.readInt32(&num);
1104 if (status != NO_ERROR) {
1105 goto invalid;
1106 }
1107
Ethan Chend6e30652013-08-04 22:49:56 -07001108 {
1109 RIL_CDMA_BroadcastSmsConfigInfo cdmaBci[num];
1110 RIL_CDMA_BroadcastSmsConfigInfo *cdmaBciPtrs[num];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001111
Ethan Chend6e30652013-08-04 22:49:56 -07001112 startRequest;
1113 for (int i = 0 ; i < num ; i++ ) {
1114 cdmaBciPtrs[i] = &cdmaBci[i];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001115
Ethan Chend6e30652013-08-04 22:49:56 -07001116 status = p.readInt32(&t);
1117 cdmaBci[i].service_category = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001118
Ethan Chend6e30652013-08-04 22:49:56 -07001119 status = p.readInt32(&t);
1120 cdmaBci[i].language = (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].selected = (uint8_t) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001124
Ethan Chend6e30652013-08-04 22:49:56 -07001125 appendPrintBuf("%s [%d: service_category=%d, language =%d, \
1126 entries.bSelected =%d]", printBuf, i, cdmaBci[i].service_category,
1127 cdmaBci[i].language, cdmaBci[i].selected);
1128 }
1129 closeRequest;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001130
Ethan Chend6e30652013-08-04 22:49:56 -07001131 if (status != NO_ERROR) {
1132 goto invalid;
1133 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001134
Ethan Chend6e30652013-08-04 22:49:56 -07001135 s_callbacks.onRequest(pRI->pCI->requestNumber,
1136 cdmaBciPtrs,
1137 num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *),
1138 pRI);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001139
1140#ifdef MEMSET_FREED
Ethan Chend6e30652013-08-04 22:49:56 -07001141 memset(cdmaBci, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo));
1142 memset(cdmaBciPtrs, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001143#endif
Ethan Chend6e30652013-08-04 22:49:56 -07001144 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001145
1146 return;
1147
1148invalid:
1149 invalidCommandBlock(pRI);
1150 return;
1151}
1152
1153static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI) {
1154 RIL_CDMA_SMS_WriteArgs rcsw;
1155 int32_t t;
1156 uint32_t ut;
1157 uint8_t uct;
1158 status_t status;
1159 int32_t digitCount;
1160
1161 memset(&rcsw, 0, sizeof(rcsw));
1162
1163 status = p.readInt32(&t);
1164 rcsw.status = t;
1165
1166 status = p.readInt32(&t);
1167 rcsw.message.uTeleserviceID = (int) t;
1168
1169 status = p.read(&uct,sizeof(uct));
1170 rcsw.message.bIsServicePresent = (uint8_t) uct;
1171
1172 status = p.readInt32(&t);
1173 rcsw.message.uServicecategory = (int) t;
1174
1175 status = p.readInt32(&t);
1176 rcsw.message.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
1177
1178 status = p.readInt32(&t);
1179 rcsw.message.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
1180
1181 status = p.readInt32(&t);
1182 rcsw.message.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
1183
1184 status = p.readInt32(&t);
1185 rcsw.message.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
1186
1187 status = p.read(&uct,sizeof(uct));
1188 rcsw.message.sAddress.number_of_digits = (uint8_t) uct;
1189
1190 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_ADDRESS_MAX; digitCount ++) {
1191 status = p.read(&uct,sizeof(uct));
1192 rcsw.message.sAddress.digits[digitCount] = (uint8_t) uct;
1193 }
1194
1195 status = p.readInt32(&t);
1196 rcsw.message.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
1197
1198 status = p.read(&uct,sizeof(uct));
1199 rcsw.message.sSubAddress.odd = (uint8_t) uct;
1200
1201 status = p.read(&uct,sizeof(uct));
1202 rcsw.message.sSubAddress.number_of_digits = (uint8_t) uct;
1203
1204 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_SUBADDRESS_MAX; digitCount ++) {
1205 status = p.read(&uct,sizeof(uct));
1206 rcsw.message.sSubAddress.digits[digitCount] = (uint8_t) uct;
1207 }
1208
1209 status = p.readInt32(&t);
1210 rcsw.message.uBearerDataLen = (int) t;
1211
1212 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_BEARER_DATA_MAX; digitCount ++) {
1213 status = p.read(&uct, sizeof(uct));
1214 rcsw.message.aBearerData[digitCount] = (uint8_t) uct;
1215 }
1216
1217 if (status != NO_ERROR) {
1218 goto invalid;
1219 }
1220
1221 startRequest;
1222 appendPrintBuf("%sstatus=%d, message.uTeleserviceID=%d, message.bIsServicePresent=%d, \
1223 message.uServicecategory=%d, message.sAddress.digit_mode=%d, \
1224 message.sAddress.number_mode=%d, \
1225 message.sAddress.number_type=%d, ",
1226 printBuf, rcsw.status, rcsw.message.uTeleserviceID, rcsw.message.bIsServicePresent,
1227 rcsw.message.uServicecategory, rcsw.message.sAddress.digit_mode,
1228 rcsw.message.sAddress.number_mode,
1229 rcsw.message.sAddress.number_type);
1230 closeRequest;
1231
1232 printRequest(pRI->token, pRI->pCI->requestNumber);
1233
1234 s_callbacks.onRequest(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw),pRI);
1235
1236#ifdef MEMSET_FREED
1237 memset(&rcsw, 0, sizeof(rcsw));
1238#endif
1239
1240 return;
1241
1242invalid:
1243 invalidCommandBlock(pRI);
1244 return;
1245
1246}
1247
Ethan Chend6e30652013-08-04 22:49:56 -07001248// For backwards compatibility in RIL_REQUEST_SETUP_DATA_CALL.
1249// Version 4 of the RIL interface adds a new PDP type parameter to support
1250// IPv6 and dual-stack PDP contexts. When dealing with a previous version of
1251// RIL, remove the parameter from the request.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001252static void dispatchDataCall(Parcel& p, RequestInfo *pRI) {
Ethan Chend6e30652013-08-04 22:49:56 -07001253 // In RIL v3, REQUEST_SETUP_DATA_CALL takes 6 parameters.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001254 const int numParamsRilV3 = 6;
1255
Ethan Chend6e30652013-08-04 22:49:56 -07001256 // The first bytes of the RIL parcel contain the request number and the
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001257 // serial number - see processCommandBuffer(). Copy them over too.
1258 int pos = p.dataPosition();
1259
1260 int numParams = p.readInt32();
1261 if (s_callbacks.version < 4 && numParams > numParamsRilV3) {
1262 Parcel p2;
1263 p2.appendFrom(&p, 0, pos);
1264 p2.writeInt32(numParamsRilV3);
1265 for(int i = 0; i < numParamsRilV3; i++) {
1266 p2.writeString16(p.readString16());
1267 }
1268 p2.setDataPosition(pos);
1269 dispatchStrings(p2, pRI);
1270 } else {
1271 p.setDataPosition(pos);
1272 dispatchStrings(p, pRI);
1273 }
1274}
1275
1276// For backwards compatibility with RILs that dont support RIL_REQUEST_VOICE_RADIO_TECH.
Ethan Chend6e30652013-08-04 22:49:56 -07001277// When all RILs handle this request, this function can be removed and
1278// the request can be sent directly to the RIL using dispatchVoid.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001279static void dispatchVoiceRadioTech(Parcel& p, RequestInfo *pRI) {
1280 RIL_RadioState state = s_callbacks.onStateRequest();
1281
1282 if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) {
1283 RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1284 }
1285
Ethan Chend6e30652013-08-04 22:49:56 -07001286 // RILs that support RADIO_STATE_ON should support this request.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001287 if (RADIO_STATE_ON == state) {
1288 dispatchVoid(p, pRI);
1289 return;
1290 }
1291
Ethan Chend6e30652013-08-04 22:49:56 -07001292 // For Older RILs, that do not support RADIO_STATE_ON, assume that they
1293 // will not support this new request either and decode Voice Radio Technology
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001294 // from Radio State
1295 voiceRadioTech = decodeVoiceRadioTechnology(state);
1296
1297 if (voiceRadioTech < 0)
1298 RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0);
1299 else
1300 RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &voiceRadioTech, sizeof(int));
1301}
1302
Ethan Chend6e30652013-08-04 22:49:56 -07001303// For backwards compatibility in RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:.
1304// When all RILs handle this request, this function can be removed and
1305// the request can be sent directly to the RIL using dispatchVoid.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001306static void dispatchCdmaSubscriptionSource(Parcel& p, RequestInfo *pRI) {
1307 RIL_RadioState state = s_callbacks.onStateRequest();
1308
1309 if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) {
1310 RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1311 }
1312
1313 // RILs that support RADIO_STATE_ON should support this request.
1314 if (RADIO_STATE_ON == state) {
1315 dispatchVoid(p, pRI);
1316 return;
1317 }
1318
Ethan Chend6e30652013-08-04 22:49:56 -07001319 // For Older RILs, that do not support RADIO_STATE_ON, assume that they
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001320 // will not support this new request either and decode CDMA Subscription Source
Ethan Chend6e30652013-08-04 22:49:56 -07001321 // from Radio State
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001322 cdmaSubscriptionSource = decodeCdmaSubscriptionSource(state);
1323
1324 if (cdmaSubscriptionSource < 0)
1325 RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0);
1326 else
1327 RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &cdmaSubscriptionSource, sizeof(int));
1328}
1329
1330static int
1331blockingWrite(int fd, const void *buffer, size_t len) {
1332 size_t writeOffset = 0;
1333 const uint8_t *toWrite;
1334
1335 toWrite = (const uint8_t *)buffer;
1336
1337 while (writeOffset < len) {
1338 ssize_t written;
1339 do {
1340 written = write (fd, toWrite + writeOffset,
1341 len - writeOffset);
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001342 } while (written < 0 && ((errno == EINTR) || (errno == EAGAIN)));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001343
1344 if (written >= 0) {
1345 writeOffset += written;
1346 } else { // written < 0
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001347 RLOGE ("RIL Response: unexpected error on write errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001348 close(fd);
1349 return -1;
1350 }
1351 }
1352
1353 return 0;
1354}
1355
1356static int
1357sendResponseRaw (const void *data, size_t dataSize) {
1358 int fd = s_fdCommand;
1359 int ret;
1360 uint32_t header;
1361
1362 if (s_fdCommand < 0) {
1363 return -1;
1364 }
1365
1366 if (dataSize > MAX_COMMAND_BYTES) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001367 RLOGE("RIL: packet larger than %u (%u)",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001368 MAX_COMMAND_BYTES, (unsigned int )dataSize);
1369
1370 return -1;
1371 }
1372
1373 pthread_mutex_lock(&s_writeMutex);
1374
1375 header = htonl(dataSize);
1376
1377 ret = blockingWrite(fd, (void *)&header, sizeof(header));
1378
1379 if (ret < 0) {
1380 pthread_mutex_unlock(&s_writeMutex);
1381 return ret;
1382 }
1383
1384 ret = blockingWrite(fd, data, dataSize);
1385
1386 if (ret < 0) {
1387 pthread_mutex_unlock(&s_writeMutex);
1388 return ret;
1389 }
1390
1391 pthread_mutex_unlock(&s_writeMutex);
1392
1393 return 0;
1394}
1395
1396static int
1397sendResponse (Parcel &p) {
1398 printResponse;
1399 return sendResponseRaw(p.data(), p.dataSize());
1400}
1401
1402/** response is an int* pointing to an array of ints*/
1403
1404static int
1405responseInts(Parcel &p, void *response, size_t responselen) {
1406 int numInts;
1407
1408 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001409 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001410 return RIL_ERRNO_INVALID_RESPONSE;
1411 }
1412 if (responselen % sizeof(int) != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001413 RLOGE("invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001414 (int)responselen, (int)sizeof(int));
1415 return RIL_ERRNO_INVALID_RESPONSE;
1416 }
1417
1418 int *p_int = (int *) response;
1419
1420 numInts = responselen / sizeof(int *);
1421 p.writeInt32 (numInts);
1422
1423 /* each int*/
1424 startResponse;
1425 for (int i = 0 ; i < numInts ; i++) {
1426 appendPrintBuf("%s%d,", printBuf, p_int[i]);
1427 p.writeInt32(p_int[i]);
1428 }
1429 removeLastChar;
1430 closeResponse;
1431
1432 return 0;
1433}
1434
1435static int
1436responseIntsGetPreferredNetworkType(Parcel &p, void *response, size_t responselen) {
1437 int numInts;
1438
1439 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001440 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001441 return RIL_ERRNO_INVALID_RESPONSE;
1442 }
1443 if (responselen % sizeof(int) != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001444 RLOGE("invalid response length %d expected multiple of %d\n",
Ethan Chend6e30652013-08-04 22:49:56 -07001445 (int)responselen, (int)sizeof(int));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001446 return RIL_ERRNO_INVALID_RESPONSE;
1447 }
1448
1449 int *p_int = (int *) response;
1450
1451 numInts = responselen / sizeof(int *);
1452 p.writeInt32 (numInts);
1453
1454 /* each int*/
1455 startResponse;
1456 for (int i = 0 ; i < numInts ; i++) {
1457 if (i == 0 && p_int[0] == 7) {
Ethan Chend6e30652013-08-04 22:49:56 -07001458 RLOGD("REQUEST_GET_PREFERRED_NETWORK_TYPE: NETWORK_MODE_GLOBAL => NETWORK_MODE_WCDMA_PREF");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001459 p_int[0] = 0;
1460 }
1461 appendPrintBuf("%s%d,", printBuf, p_int[i]);
1462 p.writeInt32(p_int[i]);
1463 }
1464 removeLastChar;
1465 closeResponse;
1466
1467 return 0;
1468}
1469
1470/** response is a char **, pointing to an array of char *'s
1471 The parcel will begin with the version */
1472static int responseStringsWithVersion(int version, Parcel &p, void *response, size_t responselen) {
1473 p.writeInt32(version);
1474 return responseStrings(p, response, responselen);
1475}
1476
1477/** response is a char **, pointing to an array of char *'s */
1478static int responseStrings(Parcel &p, void *response, size_t responselen) {
1479 return responseStrings(p, response, responselen, false);
1480}
1481
1482static int responseStringsNetworks(Parcel &p, void *response, size_t responselen) {
1483 int numStrings;
1484 int inQANElements = 5;
1485 int outQANElements = 4;
1486
1487 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001488 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001489 return RIL_ERRNO_INVALID_RESPONSE;
1490 }
1491 if (responselen % sizeof(char *) != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001492 RLOGE("invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001493 (int)responselen, (int)sizeof(char *));
1494 return RIL_ERRNO_INVALID_RESPONSE;
1495 }
Daniel Hillenbrandea4af612013-07-09 18:47:06 +02001496
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001497 if (response == NULL) {
1498 p.writeInt32 (0);
1499 } else {
1500 char **p_cur = (char **) response;
Ethan Chend6e30652013-08-04 22:49:56 -07001501 int j = 0;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001502
1503 numStrings = responselen / sizeof(char *);
1504 p.writeInt32 ((numStrings / inQANElements) * outQANElements);
1505
1506 /* each string*/
1507 startResponse;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001508 for (int i = 0 ; i < numStrings ; i++) {
1509 /* Samsung is sending 5 elements, upper layer expects 4.
1510 Drop every 5th element here */
1511 if (j == outQANElements) {
Ethan Chend6e30652013-08-04 22:49:56 -07001512 j = 0;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001513 } else {
1514 appendPrintBuf("%s%s,", printBuf, (char*)p_cur[i]);
1515 writeStringToParcel (p, p_cur[i]);
1516 j++;
1517 }
1518 }
1519 removeLastChar;
1520 closeResponse;
1521 }
1522 return 0;
1523}
1524
1525/** response is a char **, pointing to an array of char *'s */
1526static int responseStrings(Parcel &p, void *response, size_t responselen, bool network_search) {
1527 int numStrings;
1528
1529 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001530 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001531 return RIL_ERRNO_INVALID_RESPONSE;
1532 }
1533 if (responselen % sizeof(char *) != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001534 RLOGE("invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001535 (int)responselen, (int)sizeof(char *));
1536 return RIL_ERRNO_INVALID_RESPONSE;
1537 }
1538
1539 if (response == NULL) {
1540 p.writeInt32 (0);
1541 } else {
1542 char **p_cur = (char **) response;
1543
1544 numStrings = responselen / sizeof(char *);
1545 p.writeInt32 (numStrings);
1546
1547 /* each string*/
1548 startResponse;
1549 for (int i = 0 ; i < numStrings ; i++) {
1550 appendPrintBuf("%s%s,", printBuf, (char*)p_cur[i]);
1551 writeStringToParcel (p, p_cur[i]);
1552 }
1553 removeLastChar;
1554 closeResponse;
1555 }
1556 return 0;
1557}
1558
1559/**
1560 * NULL strings are accepted
1561 * FIXME currently ignores responselen
1562 */
1563static int responseString(Parcel &p, void *response, size_t responselen) {
1564 /* one string only */
1565 startResponse;
1566 appendPrintBuf("%s%s", printBuf, (char*)response);
1567 closeResponse;
1568
1569 writeStringToParcel(p, (const char *)response);
1570
1571 return 0;
1572}
1573
1574static int responseVoid(Parcel &p, void *response, size_t responselen) {
1575 startResponse;
1576 removeLastChar;
1577 return 0;
1578}
1579
1580static int responseCallList(Parcel &p, void *response, size_t responselen) {
1581 int num;
1582
1583 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001584 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001585 return RIL_ERRNO_INVALID_RESPONSE;
1586 }
1587
1588 if (responselen % sizeof (RIL_Call *) != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001589 RLOGE("invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001590 (int)responselen, (int)sizeof (RIL_Call *));
1591 return RIL_ERRNO_INVALID_RESPONSE;
1592 }
1593
1594 startResponse;
1595 /* number of call info's */
1596 num = responselen / sizeof(RIL_Call *);
1597 p.writeInt32(num);
1598
1599 for (int i = 0 ; i < num ; i++) {
1600 RIL_Call *p_cur = ((RIL_Call **) response)[i];
1601 /* each call info */
1602 p.writeInt32(p_cur->state);
1603 p.writeInt32(p_cur->index);
1604 p.writeInt32(p_cur->toa);
1605 p.writeInt32(p_cur->isMpty);
1606 p.writeInt32(p_cur->isMT);
1607 p.writeInt32(p_cur->als);
1608 p.writeInt32(p_cur->isVoice);
1609 p.writeInt32(p_cur->isVoicePrivacy);
1610 writeStringToParcel(p, p_cur->number);
1611 p.writeInt32(p_cur->numberPresentation);
1612 writeStringToParcel(p, p_cur->name);
1613 p.writeInt32(p_cur->namePresentation);
1614 // Remove when partners upgrade to version 3
1615 if ((s_callbacks.version < 3) || (p_cur->uusInfo == NULL || p_cur->uusInfo->uusData == NULL)) {
1616 p.writeInt32(0); /* UUS Information is absent */
1617 } else {
1618 RIL_UUS_Info *uusInfo = p_cur->uusInfo;
1619 p.writeInt32(1); /* UUS Information is present */
1620 p.writeInt32(uusInfo->uusType);
1621 p.writeInt32(uusInfo->uusDcs);
1622 p.writeInt32(uusInfo->uusLength);
1623 p.write(uusInfo->uusData, uusInfo->uusLength);
1624 }
1625 appendPrintBuf("%s[id=%d,%s,toa=%d,",
1626 printBuf,
1627 p_cur->index,
1628 callStateToString(p_cur->state),
1629 p_cur->toa);
1630 appendPrintBuf("%s%s,%s,als=%d,%s,%s,",
1631 printBuf,
1632 (p_cur->isMpty)?"conf":"norm",
1633 (p_cur->isMT)?"mt":"mo",
1634 p_cur->als,
1635 (p_cur->isVoice)?"voc":"nonvoc",
1636 (p_cur->isVoicePrivacy)?"evp":"noevp");
1637 appendPrintBuf("%s%s,cli=%d,name='%s',%d]",
1638 printBuf,
1639 p_cur->number,
1640 p_cur->numberPresentation,
1641 p_cur->name,
1642 p_cur->namePresentation);
1643 }
1644 removeLastChar;
1645 closeResponse;
1646
1647 return 0;
1648}
1649
1650static int responseSMS(Parcel &p, void *response, size_t responselen) {
1651 if (response == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001652 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001653 return RIL_ERRNO_INVALID_RESPONSE;
1654 }
1655
1656 if (responselen != sizeof (RIL_SMS_Response) ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001657 RLOGE("invalid response length %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001658 (int)responselen, (int)sizeof (RIL_SMS_Response));
1659 return RIL_ERRNO_INVALID_RESPONSE;
1660 }
1661
1662 RIL_SMS_Response *p_cur = (RIL_SMS_Response *) response;
1663
1664 p.writeInt32(p_cur->messageRef);
1665 writeStringToParcel(p, p_cur->ackPDU);
1666 p.writeInt32(p_cur->errorCode);
1667
1668 startResponse;
1669 appendPrintBuf("%s%d,%s,%d", printBuf, p_cur->messageRef,
1670 (char*)p_cur->ackPDU, p_cur->errorCode);
1671 closeResponse;
1672
1673 return 0;
1674}
1675
1676static int responseDataCallListV4(Parcel &p, void *response, size_t responselen)
1677{
1678 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001679 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001680 return RIL_ERRNO_INVALID_RESPONSE;
1681 }
1682
1683 if (responselen % sizeof(RIL_Data_Call_Response_v4) != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001684 RLOGE("invalid response length %d expected multiple of %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001685 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v4));
1686 return RIL_ERRNO_INVALID_RESPONSE;
1687 }
1688
1689 int num = responselen / sizeof(RIL_Data_Call_Response_v4);
1690 p.writeInt32(num);
1691
1692 RIL_Data_Call_Response_v4 *p_cur = (RIL_Data_Call_Response_v4 *) response;
1693 startResponse;
1694 int i;
1695 for (i = 0; i < num; i++) {
1696 p.writeInt32(p_cur[i].cid);
1697 p.writeInt32(p_cur[i].active);
1698 writeStringToParcel(p, p_cur[i].type);
1699 // apn is not used, so don't send.
1700 writeStringToParcel(p, p_cur[i].address);
1701 appendPrintBuf("%s[cid=%d,%s,%s,%s],", printBuf,
1702 p_cur[i].cid,
1703 (p_cur[i].active==0)?"down":"up",
1704 (char*)p_cur[i].type,
1705 (char*)p_cur[i].address);
1706 }
1707 removeLastChar;
1708 closeResponse;
1709
1710 return 0;
1711}
1712
1713static int responseDataCallList(Parcel &p, void *response, size_t responselen)
1714{
1715 // Write version
1716 p.writeInt32(s_callbacks.version);
1717
1718 if (s_callbacks.version < 5) {
1719 return responseDataCallListV4(p, response, responselen);
1720 } else {
1721 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001722 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001723 return RIL_ERRNO_INVALID_RESPONSE;
1724 }
1725
1726 if (responselen % sizeof(RIL_Data_Call_Response_v6) != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001727 RLOGE("invalid response length %d expected multiple of %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001728 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v6));
1729 return RIL_ERRNO_INVALID_RESPONSE;
1730 }
1731
1732 int num = responselen / sizeof(RIL_Data_Call_Response_v6);
1733 p.writeInt32(num);
1734
1735 RIL_Data_Call_Response_v6 *p_cur = (RIL_Data_Call_Response_v6 *) response;
1736 startResponse;
1737 int i;
1738 for (i = 0; i < num; i++) {
1739 p.writeInt32((int)p_cur[i].status);
1740 p.writeInt32(p_cur[i].suggestedRetryTime);
1741 p.writeInt32(p_cur[i].cid);
1742 p.writeInt32(p_cur[i].active);
1743 writeStringToParcel(p, p_cur[i].type);
1744 writeStringToParcel(p, p_cur[i].ifname);
1745 writeStringToParcel(p, p_cur[i].addresses);
1746 writeStringToParcel(p, p_cur[i].dnses);
1747 writeStringToParcel(p, p_cur[i].gateways);
1748 appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s],", printBuf,
1749 p_cur[i].status,
1750 p_cur[i].suggestedRetryTime,
1751 p_cur[i].cid,
1752 (p_cur[i].active==0)?"down":"up",
1753 (char*)p_cur[i].type,
1754 (char*)p_cur[i].ifname,
1755 (char*)p_cur[i].addresses,
1756 (char*)p_cur[i].dnses,
1757 (char*)p_cur[i].gateways);
1758 }
1759 removeLastChar;
1760 closeResponse;
1761 }
1762
1763 return 0;
1764}
1765
1766static int responseSetupDataCall(Parcel &p, void *response, size_t responselen)
1767{
1768 if (s_callbacks.version < 5) {
1769 return responseStringsWithVersion(s_callbacks.version, p, response, responselen);
1770 } else {
1771 return responseDataCallList(p, response, responselen);
1772 }
1773}
1774
1775static int responseRaw(Parcel &p, void *response, size_t responselen) {
1776 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001777 RLOGE("invalid response: NULL with responselen != 0");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001778 return RIL_ERRNO_INVALID_RESPONSE;
1779 }
1780
1781 // The java code reads -1 size as null byte array
1782 if (response == NULL) {
1783 p.writeInt32(-1);
1784 } else {
1785 p.writeInt32(responselen);
1786 p.write(response, responselen);
1787 }
1788
1789 return 0;
1790}
1791
1792
1793static int responseSIM_IO(Parcel &p, void *response, size_t responselen) {
1794 if (response == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001795 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001796 return RIL_ERRNO_INVALID_RESPONSE;
1797 }
1798
1799 if (responselen != sizeof (RIL_SIM_IO_Response) ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001800 RLOGE("invalid response length was %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001801 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
1802 return RIL_ERRNO_INVALID_RESPONSE;
1803 }
1804
1805 RIL_SIM_IO_Response *p_cur = (RIL_SIM_IO_Response *) response;
1806 p.writeInt32(p_cur->sw1);
1807 p.writeInt32(p_cur->sw2);
1808 writeStringToParcel(p, p_cur->simResponse);
1809
1810 startResponse;
1811 appendPrintBuf("%ssw1=0x%X,sw2=0x%X,%s", printBuf, p_cur->sw1, p_cur->sw2,
1812 (char*)p_cur->simResponse);
1813 closeResponse;
1814
1815
1816 return 0;
1817}
1818
1819static int responseCallForwards(Parcel &p, void *response, size_t responselen) {
1820 int num;
1821
1822 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001823 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001824 return RIL_ERRNO_INVALID_RESPONSE;
1825 }
1826
1827 if (responselen % sizeof(RIL_CallForwardInfo *) != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001828 RLOGE("invalid response length %d expected multiple of %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001829 (int)responselen, (int)sizeof(RIL_CallForwardInfo *));
1830 return RIL_ERRNO_INVALID_RESPONSE;
1831 }
1832
1833 /* number of call info's */
1834 num = responselen / sizeof(RIL_CallForwardInfo *);
1835 p.writeInt32(num);
1836
1837 startResponse;
1838 for (int i = 0 ; i < num ; i++) {
1839 RIL_CallForwardInfo *p_cur = ((RIL_CallForwardInfo **) response)[i];
1840
1841 p.writeInt32(p_cur->status);
1842 p.writeInt32(p_cur->reason);
1843 p.writeInt32(p_cur->serviceClass);
1844 p.writeInt32(p_cur->toa);
1845 writeStringToParcel(p, p_cur->number);
1846 p.writeInt32(p_cur->timeSeconds);
1847 appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
1848 (p_cur->status==1)?"enable":"disable",
1849 p_cur->reason, p_cur->serviceClass, p_cur->toa,
1850 (char*)p_cur->number,
1851 p_cur->timeSeconds);
1852 }
1853 removeLastChar;
1854 closeResponse;
1855
1856 return 0;
1857}
1858
1859static int responseSsn(Parcel &p, void *response, size_t responselen) {
1860 if (response == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001861 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001862 return RIL_ERRNO_INVALID_RESPONSE;
1863 }
1864
1865 if (responselen != sizeof(RIL_SuppSvcNotification)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001866 RLOGE("invalid response length was %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001867 (int)responselen, (int)sizeof (RIL_SuppSvcNotification));
1868 return RIL_ERRNO_INVALID_RESPONSE;
1869 }
1870
1871 RIL_SuppSvcNotification *p_cur = (RIL_SuppSvcNotification *) response;
1872 p.writeInt32(p_cur->notificationType);
1873 p.writeInt32(p_cur->code);
1874 p.writeInt32(p_cur->index);
1875 p.writeInt32(p_cur->type);
1876 writeStringToParcel(p, p_cur->number);
1877
1878 startResponse;
1879 appendPrintBuf("%s%s,code=%d,id=%d,type=%d,%s", printBuf,
1880 (p_cur->notificationType==0)?"mo":"mt",
1881 p_cur->code, p_cur->index, p_cur->type,
1882 (char*)p_cur->number);
1883 closeResponse;
1884
1885 return 0;
1886}
1887
1888static int responseCellList(Parcel &p, void *response, size_t responselen) {
1889 int num;
1890
1891 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001892 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001893 return RIL_ERRNO_INVALID_RESPONSE;
1894 }
1895
1896 if (responselen % sizeof (RIL_NeighboringCell *) != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001897 RLOGE("invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001898 (int)responselen, (int)sizeof (RIL_NeighboringCell *));
1899 return RIL_ERRNO_INVALID_RESPONSE;
1900 }
1901
1902 startResponse;
1903 /* number of records */
1904 num = responselen / sizeof(RIL_NeighboringCell *);
1905 p.writeInt32(num);
1906
1907 for (int i = 0 ; i < num ; i++) {
1908 RIL_NeighboringCell *p_cur = ((RIL_NeighboringCell **) response)[i];
1909
1910 p.writeInt32(p_cur->rssi);
1911 writeStringToParcel (p, p_cur->cid);
1912
1913 appendPrintBuf("%s[cid=%s,rssi=%d],", printBuf,
1914 p_cur->cid, p_cur->rssi);
1915 }
1916 removeLastChar;
1917 closeResponse;
1918
1919 return 0;
1920}
1921
1922/**
1923 * Marshall the signalInfoRecord into the parcel if it exists.
1924 */
1925static void marshallSignalInfoRecord(Parcel &p,
1926 RIL_CDMA_SignalInfoRecord &p_signalInfoRecord) {
1927 p.writeInt32(p_signalInfoRecord.isPresent);
1928 p.writeInt32(p_signalInfoRecord.signalType);
1929 p.writeInt32(p_signalInfoRecord.alertPitch);
1930 p.writeInt32(p_signalInfoRecord.signal);
1931}
1932
1933static int responseCdmaInformationRecords(Parcel &p,
1934 void *response, size_t responselen) {
1935 int num;
1936 char* string8 = NULL;
1937 int buffer_lenght;
1938 RIL_CDMA_InformationRecord *infoRec;
1939
1940 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001941 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001942 return RIL_ERRNO_INVALID_RESPONSE;
1943 }
1944
1945 if (responselen != sizeof (RIL_CDMA_InformationRecords)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001946 RLOGE("invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001947 (int)responselen, (int)sizeof (RIL_CDMA_InformationRecords *));
1948 return RIL_ERRNO_INVALID_RESPONSE;
1949 }
1950
1951 RIL_CDMA_InformationRecords *p_cur =
1952 (RIL_CDMA_InformationRecords *) response;
1953 num = MIN(p_cur->numberOfInfoRecs, RIL_CDMA_MAX_NUMBER_OF_INFO_RECS);
1954
1955 startResponse;
1956 p.writeInt32(num);
1957
1958 for (int i = 0 ; i < num ; i++) {
1959 infoRec = &p_cur->infoRec[i];
1960 p.writeInt32(infoRec->name);
1961 switch (infoRec->name) {
1962 case RIL_CDMA_DISPLAY_INFO_REC:
1963 case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
1964 if (infoRec->rec.display.alpha_len >
1965 CDMA_ALPHA_INFO_BUFFER_LENGTH) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001966 RLOGE("invalid display info response length %d \
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001967 expected not more than %d\n",
1968 (int)infoRec->rec.display.alpha_len,
1969 CDMA_ALPHA_INFO_BUFFER_LENGTH);
1970 return RIL_ERRNO_INVALID_RESPONSE;
1971 }
1972 string8 = (char*) malloc((infoRec->rec.display.alpha_len + 1)
1973 * sizeof(char) );
1974 for (int i = 0 ; i < infoRec->rec.display.alpha_len ; i++) {
1975 string8[i] = infoRec->rec.display.alpha_buf[i];
1976 }
1977 string8[(int)infoRec->rec.display.alpha_len] = '\0';
1978 writeStringToParcel(p, (const char*)string8);
1979 free(string8);
1980 string8 = NULL;
1981 break;
1982 case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
1983 case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
1984 case RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
1985 if (infoRec->rec.number.len > CDMA_NUMBER_INFO_BUFFER_LENGTH) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02001986 RLOGE("invalid display info response length %d \
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001987 expected not more than %d\n",
1988 (int)infoRec->rec.number.len,
1989 CDMA_NUMBER_INFO_BUFFER_LENGTH);
1990 return RIL_ERRNO_INVALID_RESPONSE;
1991 }
1992 string8 = (char*) malloc((infoRec->rec.number.len + 1)
1993 * sizeof(char) );
1994 for (int i = 0 ; i < infoRec->rec.number.len; i++) {
1995 string8[i] = infoRec->rec.number.buf[i];
1996 }
1997 string8[(int)infoRec->rec.number.len] = '\0';
1998 writeStringToParcel(p, (const char*)string8);
1999 free(string8);
2000 string8 = NULL;
2001 p.writeInt32(infoRec->rec.number.number_type);
2002 p.writeInt32(infoRec->rec.number.number_plan);
2003 p.writeInt32(infoRec->rec.number.pi);
2004 p.writeInt32(infoRec->rec.number.si);
2005 break;
2006 case RIL_CDMA_SIGNAL_INFO_REC:
2007 p.writeInt32(infoRec->rec.signal.isPresent);
2008 p.writeInt32(infoRec->rec.signal.signalType);
2009 p.writeInt32(infoRec->rec.signal.alertPitch);
2010 p.writeInt32(infoRec->rec.signal.signal);
2011
2012 appendPrintBuf("%sisPresent=%X, signalType=%X, \
2013 alertPitch=%X, signal=%X, ",
2014 printBuf, (int)infoRec->rec.signal.isPresent,
2015 (int)infoRec->rec.signal.signalType,
2016 (int)infoRec->rec.signal.alertPitch,
2017 (int)infoRec->rec.signal.signal);
2018 removeLastChar;
2019 break;
2020 case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
2021 if (infoRec->rec.redir.redirectingNumber.len >
2022 CDMA_NUMBER_INFO_BUFFER_LENGTH) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002023 RLOGE("invalid display info response length %d \
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002024 expected not more than %d\n",
2025 (int)infoRec->rec.redir.redirectingNumber.len,
2026 CDMA_NUMBER_INFO_BUFFER_LENGTH);
2027 return RIL_ERRNO_INVALID_RESPONSE;
2028 }
2029 string8 = (char*) malloc((infoRec->rec.redir.redirectingNumber
2030 .len + 1) * sizeof(char) );
2031 for (int i = 0;
2032 i < infoRec->rec.redir.redirectingNumber.len;
2033 i++) {
2034 string8[i] = infoRec->rec.redir.redirectingNumber.buf[i];
2035 }
2036 string8[(int)infoRec->rec.redir.redirectingNumber.len] = '\0';
2037 writeStringToParcel(p, (const char*)string8);
2038 free(string8);
2039 string8 = NULL;
2040 p.writeInt32(infoRec->rec.redir.redirectingNumber.number_type);
2041 p.writeInt32(infoRec->rec.redir.redirectingNumber.number_plan);
2042 p.writeInt32(infoRec->rec.redir.redirectingNumber.pi);
2043 p.writeInt32(infoRec->rec.redir.redirectingNumber.si);
2044 p.writeInt32(infoRec->rec.redir.redirectingReason);
2045 break;
2046 case RIL_CDMA_LINE_CONTROL_INFO_REC:
2047 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPolarityIncluded);
2048 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlToggle);
2049 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlReverse);
2050 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPowerDenial);
2051
2052 appendPrintBuf("%slineCtrlPolarityIncluded=%d, \
2053 lineCtrlToggle=%d, lineCtrlReverse=%d, \
2054 lineCtrlPowerDenial=%d, ", printBuf,
2055 (int)infoRec->rec.lineCtrl.lineCtrlPolarityIncluded,
2056 (int)infoRec->rec.lineCtrl.lineCtrlToggle,
2057 (int)infoRec->rec.lineCtrl.lineCtrlReverse,
2058 (int)infoRec->rec.lineCtrl.lineCtrlPowerDenial);
2059 removeLastChar;
2060 break;
2061 case RIL_CDMA_T53_CLIR_INFO_REC:
2062 p.writeInt32((int)(infoRec->rec.clir.cause));
2063
2064 appendPrintBuf("%scause%d", printBuf, infoRec->rec.clir.cause);
2065 removeLastChar;
2066 break;
2067 case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
2068 p.writeInt32(infoRec->rec.audioCtrl.upLink);
2069 p.writeInt32(infoRec->rec.audioCtrl.downLink);
2070
2071 appendPrintBuf("%supLink=%d, downLink=%d, ", printBuf,
2072 infoRec->rec.audioCtrl.upLink,
2073 infoRec->rec.audioCtrl.downLink);
2074 removeLastChar;
2075 break;
2076 case RIL_CDMA_T53_RELEASE_INFO_REC:
2077 // TODO(Moto): See David Krause, he has the answer:)
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002078 RLOGE("RIL_CDMA_T53_RELEASE_INFO_REC: return INVALID_RESPONSE");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002079 return RIL_ERRNO_INVALID_RESPONSE;
2080 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002081 RLOGE("Incorrect name value");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002082 return RIL_ERRNO_INVALID_RESPONSE;
2083 }
2084 }
2085 closeResponse;
2086
2087 return 0;
2088}
2089
2090static int responseRilSignalStrength(Parcel &p,
2091 void *response, size_t responselen) {
2092
2093 int gsmSignalStrength;
2094 int cdmaDbm;
2095 int evdoDbm;
2096
2097 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002098 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002099 return RIL_ERRNO_INVALID_RESPONSE;
2100 }
2101
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002102 if (responselen >= sizeof (RIL_SignalStrength_v5)) {
2103 RIL_SignalStrength_v6 *p_cur = ((RIL_SignalStrength_v6 *) response);
2104
2105 /* gsmSignalStrength */
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002106 RLOGD("gsmSignalStrength (raw)=%d", p_cur->GW_SignalStrength.signalStrength);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002107 gsmSignalStrength = p_cur->GW_SignalStrength.signalStrength & 0xFF;
2108 if (gsmSignalStrength < 0) {
2109 gsmSignalStrength = 99;
2110 } else if (gsmSignalStrength > 31 && gsmSignalStrength != 99) {
2111 gsmSignalStrength = 31;
2112 }
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002113 RLOGD("gsmSignalStrength (corrected)=%d", gsmSignalStrength);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002114 p.writeInt32(gsmSignalStrength);
2115
2116 /* gsmBitErrorRate */
2117 p.writeInt32(p_cur->GW_SignalStrength.bitErrorRate);
2118
2119 /* cdmaDbm */
Ethan Chend6e30652013-08-04 22:49:56 -07002120 RLOGD("cdmaDbm (raw)=%d", p_cur->CDMA_SignalStrength.dbm);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002121 cdmaDbm = p_cur->CDMA_SignalStrength.dbm & 0xFF;
2122 if (cdmaDbm < 0) {
2123 cdmaDbm = 99;
2124 } else if (cdmaDbm > 31 && cdmaDbm != 99) {
2125 cdmaDbm = 31;
2126 }
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002127 //RLOGD("cdmaDbm (corrected)=%d", cdmaDbm);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002128 p.writeInt32(cdmaDbm);
2129
2130 /* cdmaEcio */
2131 p.writeInt32(p_cur->CDMA_SignalStrength.ecio);
2132
2133 /* evdoDbm */
Ethan Chend6e30652013-08-04 22:49:56 -07002134 RLOGD("evdoDbm (raw)=%d", p_cur->EVDO_SignalStrength.dbm);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002135 evdoDbm = p_cur->EVDO_SignalStrength.dbm & 0xFF;
2136 if (evdoDbm < 0) {
2137 evdoDbm = 99;
2138 } else if (evdoDbm > 31 && evdoDbm != 99) {
2139 evdoDbm = 31;
2140 }
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002141 //RLOGD("evdoDbm (corrected)=%d", evdoDbm);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002142 p.writeInt32(evdoDbm);
2143
2144 /* evdoEcio */
2145 p.writeInt32(p_cur->EVDO_SignalStrength.ecio);
2146 /* evdoSnr */
2147 p.writeInt32(p_cur->EVDO_SignalStrength.signalNoiseRatio);
2148
2149 if (responselen >= sizeof (RIL_SignalStrength_v6)) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002150 /*
Ethan Chend6e30652013-08-04 22:49:56 -07002151 * Fixup LTE for backwards compatibility
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002152 */
Ethan Chend6e30652013-08-04 22:49:56 -07002153 if (s_callbacks.version <= 6) {
2154 // signalStrength: -1 -> 99
2155 if (p_cur->LTE_SignalStrength.signalStrength == -1) {
2156 p_cur->LTE_SignalStrength.signalStrength = 99;
2157 }
2158 // rsrp: -1 -> INT_MAX all other negative value to positive.
2159 // So remap here
2160 if (p_cur->LTE_SignalStrength.rsrp == -1) {
2161 p_cur->LTE_SignalStrength.rsrp = INT_MAX;
2162 } else if (p_cur->LTE_SignalStrength.rsrp < -1) {
2163 p_cur->LTE_SignalStrength.rsrp = -p_cur->LTE_SignalStrength.rsrp;
2164 }
2165 // rsrq: -1 -> INT_MAX
2166 if (p_cur->LTE_SignalStrength.rsrq == -1) {
2167 p_cur->LTE_SignalStrength.rsrq = INT_MAX;
2168 }
2169 // Not remapping rssnr is already using INT_MAX
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002170
Ethan Chend6e30652013-08-04 22:49:56 -07002171 // cqi: -1 -> INT_MAX
2172 if (p_cur->LTE_SignalStrength.cqi == -1) {
2173 p_cur->LTE_SignalStrength.cqi = INT_MAX;
2174 }
2175 }
2176 p.writeInt32(p_cur->LTE_SignalStrength.signalStrength);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002177 p.writeInt32(p_cur->LTE_SignalStrength.rsrp);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002178 p.writeInt32(p_cur->LTE_SignalStrength.rsrq);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002179 p.writeInt32(p_cur->LTE_SignalStrength.rssnr);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002180 p.writeInt32(p_cur->LTE_SignalStrength.cqi);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002181 } else {
Ethan Chend6e30652013-08-04 22:49:56 -07002182 p.writeInt32(99);
2183 p.writeInt32(INT_MAX);
2184 p.writeInt32(INT_MAX);
2185 p.writeInt32(INT_MAX);
2186 p.writeInt32(INT_MAX);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002187 }
2188
2189 startResponse;
2190 appendPrintBuf("%s[signalStrength=%d,bitErrorRate=%d,\
2191 CDMA_SS.dbm=%d,CDMA_SSecio=%d,\
2192 EVDO_SS.dbm=%d,EVDO_SS.ecio=%d,\
2193 EVDO_SS.signalNoiseRatio=%d,\
2194 LTE_SS.signalStrength=%d,LTE_SS.rsrp=%d,LTE_SS.rsrq=%d,\
2195 LTE_SS.rssnr=%d,LTE_SS.cqi=%d]",
2196 printBuf,
2197 gsmSignalStrength,
2198 p_cur->GW_SignalStrength.bitErrorRate,
2199 cdmaDbm,
2200 p_cur->CDMA_SignalStrength.ecio,
2201 evdoDbm,
2202 p_cur->EVDO_SignalStrength.ecio,
2203 p_cur->EVDO_SignalStrength.signalNoiseRatio,
2204 p_cur->LTE_SignalStrength.signalStrength,
2205 p_cur->LTE_SignalStrength.rsrp,
2206 p_cur->LTE_SignalStrength.rsrq,
2207 p_cur->LTE_SignalStrength.rssnr,
2208 p_cur->LTE_SignalStrength.cqi);
2209 closeResponse;
2210
2211 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002212 RLOGE("invalid response length");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002213 return RIL_ERRNO_INVALID_RESPONSE;
2214 }
2215
2216 return 0;
2217}
2218
2219static int responseCallRing(Parcel &p, void *response, size_t responselen) {
2220 if ((response == NULL) || (responselen == 0)) {
2221 return responseVoid(p, response, responselen);
2222 } else {
2223 return responseCdmaSignalInfoRecord(p, response, responselen);
2224 }
2225}
2226
2227static int responseCdmaSignalInfoRecord(Parcel &p, void *response, size_t responselen) {
2228 if (response == NULL || responselen == 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002229 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002230 return RIL_ERRNO_INVALID_RESPONSE;
2231 }
2232
2233 if (responselen != sizeof (RIL_CDMA_SignalInfoRecord)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002234 RLOGE("invalid response length %d expected sizeof (RIL_CDMA_SignalInfoRecord) of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002235 (int)responselen, (int)sizeof (RIL_CDMA_SignalInfoRecord));
2236 return RIL_ERRNO_INVALID_RESPONSE;
2237 }
2238
2239 startResponse;
2240
2241 RIL_CDMA_SignalInfoRecord *p_cur = ((RIL_CDMA_SignalInfoRecord *) response);
2242 marshallSignalInfoRecord(p, *p_cur);
2243
2244 appendPrintBuf("%s[isPresent=%d,signalType=%d,alertPitch=%d\
2245 signal=%d]",
2246 printBuf,
2247 p_cur->isPresent,
2248 p_cur->signalType,
2249 p_cur->alertPitch,
2250 p_cur->signal);
2251
2252 closeResponse;
2253 return 0;
2254}
2255
2256static int responseCdmaCallWaiting(Parcel &p, void *response,
2257 size_t responselen) {
2258 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002259 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002260 return RIL_ERRNO_INVALID_RESPONSE;
2261 }
2262
2263 if (responselen < sizeof(RIL_CDMA_CallWaiting_v6)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002264 RLOGW("Upgrade to ril version %d\n", RIL_VERSION);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002265 }
2266
2267 RIL_CDMA_CallWaiting_v6 *p_cur = ((RIL_CDMA_CallWaiting_v6 *) response);
2268
2269 writeStringToParcel(p, p_cur->number);
2270 p.writeInt32(p_cur->numberPresentation);
2271 writeStringToParcel(p, p_cur->name);
2272 marshallSignalInfoRecord(p, p_cur->signalInfoRecord);
2273
2274 if (responselen >= sizeof(RIL_CDMA_CallWaiting_v6)) {
2275 p.writeInt32(p_cur->number_type);
2276 p.writeInt32(p_cur->number_plan);
2277 } else {
2278 p.writeInt32(0);
2279 p.writeInt32(0);
2280 }
2281
2282 startResponse;
2283 appendPrintBuf("%snumber=%s,numberPresentation=%d, name=%s,\
2284 signalInfoRecord[isPresent=%d,signalType=%d,alertPitch=%d\
2285 signal=%d,number_type=%d,number_plan=%d]",
2286 printBuf,
2287 p_cur->number,
2288 p_cur->numberPresentation,
2289 p_cur->name,
2290 p_cur->signalInfoRecord.isPresent,
2291 p_cur->signalInfoRecord.signalType,
2292 p_cur->signalInfoRecord.alertPitch,
2293 p_cur->signalInfoRecord.signal,
2294 p_cur->number_type,
2295 p_cur->number_plan);
2296 closeResponse;
2297
2298 return 0;
2299}
2300
2301static int responseSimRefresh(Parcel &p, void *response, size_t responselen) {
2302 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002303 RLOGE("responseSimRefresh: invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002304 return RIL_ERRNO_INVALID_RESPONSE;
2305 }
2306
2307 startResponse;
2308 if (s_callbacks.version == 7) {
2309 RIL_SimRefreshResponse_v7 *p_cur = ((RIL_SimRefreshResponse_v7 *) response);
2310 p.writeInt32(p_cur->result);
2311 p.writeInt32(p_cur->ef_id);
2312 writeStringToParcel(p, p_cur->aid);
2313
2314 appendPrintBuf("%sresult=%d, ef_id=%d, aid=%s",
2315 printBuf,
2316 p_cur->result,
2317 p_cur->ef_id,
2318 p_cur->aid);
2319 } else {
2320 int *p_cur = ((int *) response);
2321 p.writeInt32(p_cur[0]);
2322 p.writeInt32(p_cur[1]);
2323 writeStringToParcel(p, NULL);
2324
2325 appendPrintBuf("%sresult=%d, ef_id=%d",
2326 printBuf,
2327 p_cur[0],
2328 p_cur[1]);
2329 }
2330 closeResponse;
2331
2332 return 0;
2333}
2334
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002335static int responseCellInfoList(Parcel &p, void *response, size_t responselen)
2336{
2337 if (response == NULL && responselen != 0) {
2338 RLOGE("invalid response: NULL");
2339 return RIL_ERRNO_INVALID_RESPONSE;
2340 }
2341
2342 if (responselen % sizeof(RIL_CellInfo) != 0) {
2343 RLOGE("invalid response length %d expected multiple of %d",
2344 (int)responselen, (int)sizeof(RIL_CellInfo));
2345 return RIL_ERRNO_INVALID_RESPONSE;
2346 }
2347
2348 int num = responselen / sizeof(RIL_CellInfo);
2349 p.writeInt32(num);
2350
2351 RIL_CellInfo *p_cur = (RIL_CellInfo *) response;
2352 startResponse;
2353 int i;
2354 for (i = 0; i < num; i++) {
2355 appendPrintBuf("%s[%d: type=%d,registered=%d,timeStampType=%d,timeStamp=%lld", printBuf, i,
2356 p_cur->cellInfoType, p_cur->registered, p_cur->timeStampType, p_cur->timeStamp);
2357 p.writeInt32((int)p_cur->cellInfoType);
2358 p.writeInt32(p_cur->registered);
2359 p.writeInt32(p_cur->timeStampType);
2360 p.writeInt64(p_cur->timeStamp);
2361 switch(p_cur->cellInfoType) {
2362 case RIL_CELL_INFO_TYPE_GSM: {
2363 appendPrintBuf("%s GSM id: mcc=%d,mnc=%d,lac=%d,cid=%d,", printBuf,
2364 p_cur->CellInfo.gsm.cellIdentityGsm.mcc,
2365 p_cur->CellInfo.gsm.cellIdentityGsm.mnc,
2366 p_cur->CellInfo.gsm.cellIdentityGsm.lac,
2367 p_cur->CellInfo.gsm.cellIdentityGsm.cid);
2368 appendPrintBuf("%s gsmSS: ss=%d,ber=%d],", printBuf,
2369 p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength,
2370 p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
2371
2372 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mcc);
2373 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mnc);
2374 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.lac);
2375 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.cid);
2376 p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength);
2377 p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
2378 break;
2379 }
2380 case RIL_CELL_INFO_TYPE_WCDMA: {
2381 appendPrintBuf("%s WCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,psc=%d,", printBuf,
2382 p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc,
2383 p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc,
2384 p_cur->CellInfo.wcdma.cellIdentityWcdma.lac,
2385 p_cur->CellInfo.wcdma.cellIdentityWcdma.cid,
2386 p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
2387 appendPrintBuf("%s wcdmaSS: ss=%d,ber=%d],", printBuf,
2388 p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength,
2389 p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
2390
2391 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc);
2392 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc);
2393 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.lac);
2394 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.cid);
2395 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
2396 p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength);
2397 p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
2398 break;
2399 }
2400 case RIL_CELL_INFO_TYPE_CDMA: {
2401 appendPrintBuf("%s CDMA id: nId=%d,sId=%d,bsId=%d,long=%d,lat=%d", printBuf,
2402 p_cur->CellInfo.cdma.cellIdentityCdma.networkId,
2403 p_cur->CellInfo.cdma.cellIdentityCdma.systemId,
2404 p_cur->CellInfo.cdma.cellIdentityCdma.basestationId,
2405 p_cur->CellInfo.cdma.cellIdentityCdma.longitude,
2406 p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
2407
2408 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.networkId);
2409 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.systemId);
2410 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.basestationId);
2411 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.longitude);
2412 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
2413
2414 appendPrintBuf("%s cdmaSS: dbm=%d ecio=%d evdoSS: dbm=%d,ecio=%d,snr=%d", printBuf,
2415 p_cur->CellInfo.cdma.signalStrengthCdma.dbm,
2416 p_cur->CellInfo.cdma.signalStrengthCdma.ecio,
2417 p_cur->CellInfo.cdma.signalStrengthEvdo.dbm,
2418 p_cur->CellInfo.cdma.signalStrengthEvdo.ecio,
2419 p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
2420
2421 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.dbm);
2422 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.ecio);
2423 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.dbm);
2424 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.ecio);
2425 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
2426 break;
2427 }
2428 case RIL_CELL_INFO_TYPE_LTE: {
2429 appendPrintBuf("%s LTE id: mcc=%d,mnc=%d,ci=%d,pci=%d,tac=%d", printBuf,
2430 p_cur->CellInfo.lte.cellIdentityLte.mcc,
2431 p_cur->CellInfo.lte.cellIdentityLte.mnc,
2432 p_cur->CellInfo.lte.cellIdentityLte.ci,
2433 p_cur->CellInfo.lte.cellIdentityLte.pci,
2434 p_cur->CellInfo.lte.cellIdentityLte.tac);
2435
2436 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mcc);
2437 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mnc);
2438 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.ci);
2439 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.pci);
2440 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.tac);
2441
2442 appendPrintBuf("%s lteSS: ss=%d,rsrp=%d,rsrq=%d,rssnr=%d,cqi=%d,ta=%d", printBuf,
2443 p_cur->CellInfo.lte.signalStrengthLte.signalStrength,
2444 p_cur->CellInfo.lte.signalStrengthLte.rsrp,
2445 p_cur->CellInfo.lte.signalStrengthLte.rsrq,
2446 p_cur->CellInfo.lte.signalStrengthLte.rssnr,
2447 p_cur->CellInfo.lte.signalStrengthLte.cqi,
2448 p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
2449 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.signalStrength);
2450 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrp);
2451 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrq);
2452 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rssnr);
2453 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.cqi);
2454 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
2455 break;
2456 }
2457 }
2458 p_cur += 1;
2459 }
2460 removeLastChar;
2461 closeResponse;
2462
2463 return 0;
2464}
2465
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002466static void triggerEvLoop() {
2467 int ret;
2468 if (!pthread_equal(pthread_self(), s_tid_dispatch)) {
2469 /* trigger event loop to wakeup. No reason to do this,
2470 * if we're in the event loop thread */
2471 do {
2472 ret = write (s_fdWakeupWrite, " ", 1);
2473 } while (ret < 0 && errno == EINTR);
2474 }
2475}
2476
2477static void rilEventAddWakeup(struct ril_event *ev) {
2478 ril_event_add(ev);
2479 triggerEvLoop();
2480}
2481
2482static void sendSimStatusAppInfo(Parcel &p, int num_apps, RIL_AppStatus appStatus[]) {
2483 p.writeInt32(num_apps);
2484 startResponse;
2485 for (int i = 0; i < num_apps; i++) {
2486 p.writeInt32(appStatus[i].app_type);
2487 p.writeInt32(appStatus[i].app_state);
2488 p.writeInt32(appStatus[i].perso_substate);
2489 writeStringToParcel(p, (const char*)(appStatus[i].aid_ptr));
2490 writeStringToParcel(p, (const char*)
2491 (appStatus[i].app_label_ptr));
2492 p.writeInt32(appStatus[i].pin1_replaced);
2493 p.writeInt32(appStatus[i].pin1);
2494 p.writeInt32(appStatus[i].pin2);
2495 appendPrintBuf("%s[app_type=%d,app_state=%d,perso_substate=%d,\
2496 aid_ptr=%s,app_label_ptr=%s,pin1_replaced=%d,pin1=%d,pin2=%d],",
2497 printBuf,
2498 appStatus[i].app_type,
2499 appStatus[i].app_state,
2500 appStatus[i].perso_substate,
2501 appStatus[i].aid_ptr,
2502 appStatus[i].app_label_ptr,
2503 appStatus[i].pin1_replaced,
2504 appStatus[i].pin1,
2505 appStatus[i].pin2);
2506 }
2507 closeResponse;
2508}
2509
2510static int responseSimStatus(Parcel &p, void *response, size_t responselen) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002511 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002512 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002513 return RIL_ERRNO_INVALID_RESPONSE;
2514 }
2515
2516 if (responselen == sizeof (RIL_CardStatus_v6)) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002517 RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
2518
2519 p.writeInt32(p_cur->card_state);
2520 p.writeInt32(p_cur->universal_pin_state);
2521 p.writeInt32(p_cur->gsm_umts_subscription_app_index);
2522 p.writeInt32(p_cur->cdma_subscription_app_index);
2523 p.writeInt32(p_cur->ims_subscription_app_index);
2524
2525 sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
2526 } else if (responselen == sizeof (RIL_CardStatus_v5)) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002527 RIL_CardStatus_v5 *p_cur = ((RIL_CardStatus_v5 *) response);
2528
2529 p.writeInt32(p_cur->card_state);
2530 p.writeInt32(p_cur->universal_pin_state);
2531 p.writeInt32(p_cur->gsm_umts_subscription_app_index);
2532 p.writeInt32(p_cur->cdma_subscription_app_index);
2533 p.writeInt32(-1);
2534
2535 sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
2536 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002537 RLOGE("responseSimStatus: A RilCardStatus_v6 or _v5 expected\n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002538 return RIL_ERRNO_INVALID_RESPONSE;
2539 }
2540
2541 return 0;
2542}
2543
2544static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen) {
2545 int num = responselen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *);
2546 p.writeInt32(num);
2547
2548 startResponse;
2549 RIL_GSM_BroadcastSmsConfigInfo **p_cur =
2550 (RIL_GSM_BroadcastSmsConfigInfo **) response;
2551 for (int i = 0; i < num; i++) {
2552 p.writeInt32(p_cur[i]->fromServiceId);
2553 p.writeInt32(p_cur[i]->toServiceId);
2554 p.writeInt32(p_cur[i]->fromCodeScheme);
2555 p.writeInt32(p_cur[i]->toCodeScheme);
2556 p.writeInt32(p_cur[i]->selected);
2557
2558 appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId=%d, \
2559 fromCodeScheme=%d, toCodeScheme=%d, selected =%d]",
2560 printBuf, i, p_cur[i]->fromServiceId, p_cur[i]->toServiceId,
2561 p_cur[i]->fromCodeScheme, p_cur[i]->toCodeScheme,
2562 p_cur[i]->selected);
2563 }
2564 closeResponse;
2565
2566 return 0;
2567}
2568
2569static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen) {
2570 RIL_CDMA_BroadcastSmsConfigInfo **p_cur =
2571 (RIL_CDMA_BroadcastSmsConfigInfo **) response;
2572
2573 int num = responselen / sizeof (RIL_CDMA_BroadcastSmsConfigInfo *);
2574 p.writeInt32(num);
2575
2576 startResponse;
2577 for (int i = 0 ; i < num ; i++ ) {
2578 p.writeInt32(p_cur[i]->service_category);
2579 p.writeInt32(p_cur[i]->language);
2580 p.writeInt32(p_cur[i]->selected);
2581
2582 appendPrintBuf("%s [%d: srvice_category=%d, language =%d, \
2583 selected =%d], ",
2584 printBuf, i, p_cur[i]->service_category, p_cur[i]->language,
2585 p_cur[i]->selected);
2586 }
2587 closeResponse;
2588
2589 return 0;
2590}
2591
2592static int responseCdmaSms(Parcel &p, void *response, size_t responselen) {
2593 int num;
2594 int digitCount;
2595 int digitLimit;
2596 uint8_t uct;
2597 void* dest;
2598
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002599 RLOGD("Inside responseCdmaSms");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002600
2601 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002602 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002603 return RIL_ERRNO_INVALID_RESPONSE;
2604 }
2605
2606 if (responselen != sizeof(RIL_CDMA_SMS_Message)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002607 RLOGE("invalid response length was %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002608 (int)responselen, (int)sizeof(RIL_CDMA_SMS_Message));
2609 return RIL_ERRNO_INVALID_RESPONSE;
2610 }
2611
2612 RIL_CDMA_SMS_Message *p_cur = (RIL_CDMA_SMS_Message *) response;
2613 p.writeInt32(p_cur->uTeleserviceID);
2614 p.write(&(p_cur->bIsServicePresent),sizeof(uct));
2615 p.writeInt32(p_cur->uServicecategory);
2616 p.writeInt32(p_cur->sAddress.digit_mode);
2617 p.writeInt32(p_cur->sAddress.number_mode);
2618 p.writeInt32(p_cur->sAddress.number_type);
2619 p.writeInt32(p_cur->sAddress.number_plan);
2620 p.write(&(p_cur->sAddress.number_of_digits), sizeof(uct));
2621 digitLimit= MIN((p_cur->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
2622 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
2623 p.write(&(p_cur->sAddress.digits[digitCount]),sizeof(uct));
2624 }
2625
2626 p.writeInt32(p_cur->sSubAddress.subaddressType);
2627 p.write(&(p_cur->sSubAddress.odd),sizeof(uct));
2628 p.write(&(p_cur->sSubAddress.number_of_digits),sizeof(uct));
2629 digitLimit= MIN((p_cur->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
2630 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
2631 p.write(&(p_cur->sSubAddress.digits[digitCount]),sizeof(uct));
2632 }
2633
2634 digitLimit= MIN((p_cur->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
2635 p.writeInt32(p_cur->uBearerDataLen);
2636 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
2637 p.write(&(p_cur->aBearerData[digitCount]), sizeof(uct));
2638 }
2639
2640 startResponse;
2641 appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
2642 sAddress.digit_mode=%d, sAddress.number_mode=%d, sAddress.number_type=%d, ",
2643 printBuf, p_cur->uTeleserviceID,p_cur->bIsServicePresent,p_cur->uServicecategory,
2644 p_cur->sAddress.digit_mode, p_cur->sAddress.number_mode,p_cur->sAddress.number_type);
2645 closeResponse;
2646
2647 return 0;
2648}
2649
2650/**
2651 * A write on the wakeup fd is done just to pop us out of select()
2652 * We empty the buffer here and then ril_event will reset the timers on the
2653 * way back down
2654 */
2655static void processWakeupCallback(int fd, short flags, void *param) {
2656 char buff[16];
2657 int ret;
2658
Ethan Chend6e30652013-08-04 22:49:56 -07002659 RLOGV("processWakeupCallback");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002660
2661 /* empty our wakeup socket out */
2662 do {
2663 ret = read(s_fdWakeupRead, &buff, sizeof(buff));
2664 } while (ret > 0 || (ret < 0 && errno == EINTR));
2665}
2666
2667static void onCommandsSocketClosed() {
2668 int ret;
2669 RequestInfo *p_cur;
2670
2671 /* mark pending requests as "cancelled" so we dont report responses */
2672
2673 ret = pthread_mutex_lock(&s_pendingRequestsMutex);
2674 assert (ret == 0);
2675
2676 p_cur = s_pendingRequests;
2677
2678 for (p_cur = s_pendingRequests
2679 ; p_cur != NULL
2680 ; p_cur = p_cur->p_next
2681 ) {
2682 p_cur->cancelled = 1;
2683 }
2684
2685 ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
2686 assert (ret == 0);
2687}
2688
2689static void processCommandsCallback(int fd, short flags, void *param) {
2690 RecordStream *p_rs;
2691 void *p_record;
2692 size_t recordlen;
2693 int ret;
2694
2695 assert(fd == s_fdCommand);
2696
2697 p_rs = (RecordStream *)param;
2698
2699 for (;;) {
2700 /* loop until EAGAIN/EINTR, end of stream, or other error */
2701 ret = record_stream_get_next(p_rs, &p_record, &recordlen);
2702
2703 if (ret == 0 && p_record == NULL) {
2704 /* end-of-stream */
2705 break;
2706 } else if (ret < 0) {
2707 break;
2708 } else if (ret == 0) { /* && p_record != NULL */
2709 processCommandBuffer(p_record, recordlen);
2710 }
2711 }
2712
2713 if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) {
2714 /* fatal error or end-of-stream */
2715 if (ret != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002716 RLOGE("error on reading command socket errno:%d\n", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002717 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002718 RLOGW("EOS. Closing command socket.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002719 }
2720
2721 close(s_fdCommand);
2722 s_fdCommand = -1;
2723
2724 ril_event_del(&s_commands_event);
2725
2726 record_stream_free(p_rs);
2727
2728 /* start listening for new connections again */
2729 rilEventAddWakeup(&s_listen_event);
2730
2731 onCommandsSocketClosed();
2732 }
2733}
2734
2735
2736static void onNewCommandConnect() {
2737 // Inform we are connected and the ril version
2738 int rilVer = s_callbacks.version;
2739 RIL_onUnsolicitedResponse(RIL_UNSOL_RIL_CONNECTED,
2740 &rilVer, sizeof(rilVer));
2741
2742 // implicit radio state changed
2743 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
2744 NULL, 0);
2745
2746 // Send last NITZ time data, in case it was missed
2747 if (s_lastNITZTimeData != NULL) {
2748 sendResponseRaw(s_lastNITZTimeData, s_lastNITZTimeDataSize);
2749
2750 free(s_lastNITZTimeData);
2751 s_lastNITZTimeData = NULL;
2752 }
2753
2754 // Get version string
2755 if (s_callbacks.getVersion != NULL) {
2756 const char *version;
2757 version = s_callbacks.getVersion();
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002758 RLOGI("RIL Daemon version: %s\n", version);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002759
2760 property_set(PROPERTY_RIL_IMPL, version);
2761 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002762 RLOGI("RIL Daemon version: unavailable\n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002763 property_set(PROPERTY_RIL_IMPL, "unavailable");
2764 }
2765
2766}
2767
2768static void listenCallback (int fd, short flags, void *param) {
2769 int ret;
2770 int err;
2771 int is_phone_socket;
2772 RecordStream *p_rs;
2773
2774 struct sockaddr_un peeraddr;
2775 socklen_t socklen = sizeof (peeraddr);
2776
2777 struct ucred creds;
2778 socklen_t szCreds = sizeof(creds);
2779
2780 struct passwd *pwd = NULL;
2781
2782 assert (s_fdCommand < 0);
2783 assert (fd == s_fdListen);
2784
2785 s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);
2786
2787 if (s_fdCommand < 0 ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002788 RLOGE("Error on accept() errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002789 /* start listening for new connections again */
2790 rilEventAddWakeup(&s_listen_event);
2791 return;
2792 }
2793
2794 /* check the credential of the other side and only accept socket from
2795 * phone process
2796 */
2797 errno = 0;
2798 is_phone_socket = 0;
2799
2800 err = getsockopt(s_fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds);
2801
2802 if (err == 0 && szCreds > 0) {
2803 errno = 0;
2804 pwd = getpwuid(creds.uid);
2805 if (pwd != NULL) {
2806 if (strcmp(pwd->pw_name, PHONE_PROCESS) == 0) {
2807 is_phone_socket = 1;
2808 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002809 RLOGE("RILD can't accept socket from process %s", pwd->pw_name);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002810 }
2811 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002812 RLOGE("Error on getpwuid() errno: %d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002813 }
2814 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002815 RLOGD("Error on getsockopt() errno: %d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002816 }
2817
2818 if ( !is_phone_socket ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002819 RLOGE("RILD must accept socket from %s", PHONE_PROCESS);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002820
2821 close(s_fdCommand);
2822 s_fdCommand = -1;
2823
2824 onCommandsSocketClosed();
2825
2826 /* start listening for new connections again */
2827 rilEventAddWakeup(&s_listen_event);
2828
2829 return;
2830 }
2831
2832 ret = fcntl(s_fdCommand, F_SETFL, O_NONBLOCK);
2833
2834 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002835 RLOGE ("Error setting O_NONBLOCK errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002836 }
2837
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002838 RLOGI("libril: new connection");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002839
2840 p_rs = record_stream_new(s_fdCommand, MAX_COMMAND_BYTES);
2841
2842 ril_event_set (&s_commands_event, s_fdCommand, 1,
2843 processCommandsCallback, p_rs);
2844
2845 rilEventAddWakeup (&s_commands_event);
2846
2847 onNewCommandConnect();
2848}
2849
2850static void freeDebugCallbackArgs(int number, char **args) {
2851 for (int i = 0; i < number; i++) {
2852 if (args[i] != NULL) {
2853 free(args[i]);
2854 }
2855 }
2856 free(args);
2857}
2858
2859static void debugCallback (int fd, short flags, void *param) {
2860 int acceptFD, option;
2861 struct sockaddr_un peeraddr;
2862 socklen_t socklen = sizeof (peeraddr);
2863 int data;
2864 unsigned int qxdm_data[6];
2865 const char *deactData[1] = {"1"};
2866 char *actData[1];
2867 RIL_Dial dialData;
2868 int hangupData[1] = {1};
2869 int number;
2870 char **args;
2871
2872 acceptFD = accept (fd, (sockaddr *) &peeraddr, &socklen);
2873
2874 if (acceptFD < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002875 RLOGE ("error accepting on debug port: %d\n", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002876 return;
2877 }
2878
2879 if (recv(acceptFD, &number, sizeof(int), 0) != sizeof(int)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002880 RLOGE ("error reading on socket: number of Args: \n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002881 return;
2882 }
2883 args = (char **) malloc(sizeof(char*) * number);
2884
2885 for (int i = 0; i < number; i++) {
2886 int len;
2887 if (recv(acceptFD, &len, sizeof(int), 0) != sizeof(int)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002888 RLOGE ("error reading on socket: Len of Args: \n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002889 freeDebugCallbackArgs(i, args);
2890 return;
2891 }
2892 // +1 for null-term
2893 args[i] = (char *) malloc((sizeof(char) * len) + 1);
2894 if (recv(acceptFD, args[i], sizeof(char) * len, 0)
2895 != (int)sizeof(char) * len) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002896 RLOGE ("error reading on socket: Args[%d] \n", i);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002897 freeDebugCallbackArgs(i, args);
2898 return;
2899 }
2900 char * buf = args[i];
2901 buf[len] = 0;
2902 }
2903
2904 switch (atoi(args[0])) {
2905 case 0:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002906 RLOGI ("Connection on debug port: issuing reset.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002907 issueLocalRequest(RIL_REQUEST_RESET_RADIO, NULL, 0);
2908 break;
2909 case 1:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002910 RLOGI ("Connection on debug port: issuing radio power off.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002911 data = 0;
2912 issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int));
2913 // Close the socket
2914 close(s_fdCommand);
2915 s_fdCommand = -1;
2916 break;
2917 case 2:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002918 RLOGI ("Debug port: issuing unsolicited voice network change.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002919 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
2920 NULL, 0);
2921 break;
2922 case 3:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002923 RLOGI ("Debug port: QXDM log enable.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002924 qxdm_data[0] = 65536; // head.func_tag
2925 qxdm_data[1] = 16; // head.len
2926 qxdm_data[2] = 1; // mode: 1 for 'start logging'
2927 qxdm_data[3] = 32; // log_file_size: 32megabytes
2928 qxdm_data[4] = 0; // log_mask
2929 qxdm_data[5] = 8; // log_max_fileindex
2930 issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
2931 6 * sizeof(int));
2932 break;
2933 case 4:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002934 RLOGI ("Debug port: QXDM log disable.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002935 qxdm_data[0] = 65536;
2936 qxdm_data[1] = 16;
2937 qxdm_data[2] = 0; // mode: 0 for 'stop logging'
2938 qxdm_data[3] = 32;
2939 qxdm_data[4] = 0;
2940 qxdm_data[5] = 8;
2941 issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
2942 6 * sizeof(int));
2943 break;
2944 case 5:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002945 RLOGI("Debug port: Radio On");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002946 data = 1;
2947 issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int));
2948 sleep(2);
2949 // Set network selection automatic.
2950 issueLocalRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, NULL, 0);
2951 break;
2952 case 6:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002953 RLOGI("Debug port: Setup Data Call, Apn :%s\n", args[1]);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002954 actData[0] = args[1];
2955 issueLocalRequest(RIL_REQUEST_SETUP_DATA_CALL, &actData,
2956 sizeof(actData));
2957 break;
2958 case 7:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002959 RLOGI("Debug port: Deactivate Data Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002960 issueLocalRequest(RIL_REQUEST_DEACTIVATE_DATA_CALL, &deactData,
2961 sizeof(deactData));
2962 break;
2963 case 8:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002964 RLOGI("Debug port: Dial Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002965 dialData.clir = 0;
2966 dialData.address = args[1];
2967 issueLocalRequest(RIL_REQUEST_DIAL, &dialData, sizeof(dialData));
2968 break;
2969 case 9:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002970 RLOGI("Debug port: Answer Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002971 issueLocalRequest(RIL_REQUEST_ANSWER, NULL, 0);
2972 break;
2973 case 10:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002974 RLOGI("Debug port: End Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002975 issueLocalRequest(RIL_REQUEST_HANGUP, &hangupData,
2976 sizeof(hangupData));
2977 break;
2978 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002979 RLOGE ("Invalid request");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002980 break;
2981 }
2982 freeDebugCallbackArgs(number, args);
2983 close(acceptFD);
2984}
2985
2986
2987static void userTimerCallback (int fd, short flags, void *param) {
2988 UserCallbackInfo *p_info;
2989
2990 p_info = (UserCallbackInfo *)param;
2991
2992 p_info->p_callback(p_info->userParam);
2993
2994
2995 // FIXME generalize this...there should be a cancel mechanism
2996 if (s_last_wake_timeout_info != NULL && s_last_wake_timeout_info == p_info) {
2997 s_last_wake_timeout_info = NULL;
2998 }
2999
3000 free(p_info);
3001}
3002
3003
3004static void *
3005eventLoop(void *param) {
3006 int ret;
3007 int filedes[2];
3008
3009 ril_event_init();
3010
3011 pthread_mutex_lock(&s_startupMutex);
3012
3013 s_started = 1;
3014 pthread_cond_broadcast(&s_startupCond);
3015
3016 pthread_mutex_unlock(&s_startupMutex);
3017
3018 ret = pipe(filedes);
3019
3020 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003021 RLOGE("Error in pipe() errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003022 return NULL;
3023 }
3024
3025 s_fdWakeupRead = filedes[0];
3026 s_fdWakeupWrite = filedes[1];
3027
3028 fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
3029
3030 ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
3031 processWakeupCallback, NULL);
3032
3033 rilEventAddWakeup (&s_wakeupfd_event);
3034
3035 // Only returns on error
3036 ril_event_loop();
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003037 RLOGE ("error in event_loop_base errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003038 // kill self to restart on error
3039 kill(0, SIGKILL);
3040
3041 return NULL;
3042}
3043
3044extern "C" void
3045RIL_startEventLoop(void) {
3046 int ret;
3047 pthread_attr_t attr;
3048
3049 /* spin up eventLoop thread and wait for it to get started */
3050 s_started = 0;
3051 pthread_mutex_lock(&s_startupMutex);
3052
3053 pthread_attr_init (&attr);
3054 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
3055 ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
3056
3057 while (s_started == 0) {
3058 pthread_cond_wait(&s_startupCond, &s_startupMutex);
3059 }
3060
3061 pthread_mutex_unlock(&s_startupMutex);
3062
3063 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003064 RLOGE("Failed to create dispatch thread errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003065 return;
3066 }
3067}
3068
3069// Used for testing purpose only.
3070extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) {
3071 memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
3072}
3073
3074extern "C" void
3075RIL_register (const RIL_RadioFunctions *callbacks) {
3076 int ret;
3077 int flags;
3078
3079 if (callbacks == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003080 RLOGE("RIL_register: RIL_RadioFunctions * null");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003081 return;
3082 }
3083 if (callbacks->version < RIL_VERSION_MIN) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003084 RLOGE("RIL_register: version %d is to old, min version is %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003085 callbacks->version, RIL_VERSION_MIN);
3086 return;
3087 }
3088 if (callbacks->version > RIL_VERSION) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003089 RLOGE("RIL_register: version %d is too new, max version is %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003090 callbacks->version, RIL_VERSION);
3091 return;
3092 }
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003093 RLOGE("RIL_register: RIL version %d", callbacks->version);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003094
3095 if (s_registerCalled > 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003096 RLOGE("RIL_register has been called more than once. "
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003097 "Subsequent call ignored");
3098 return;
3099 }
3100
3101 memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
3102
3103 s_registerCalled = 1;
3104
3105 // Little self-check
3106
3107 for (int i = 0; i < (int)NUM_ELEMS(s_commands); i++) {
3108 assert(i == s_commands[i].requestNumber);
3109 }
3110
3111 for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses); i++) {
3112 assert(i + RIL_UNSOL_RESPONSE_BASE
3113 == s_unsolResponses[i].requestNumber);
3114 }
3115
3116 // New rild impl calls RIL_startEventLoop() first
3117 // old standalone impl wants it here.
3118
3119 if (s_started == 0) {
3120 RIL_startEventLoop();
3121 }
3122
3123 // start listen socket
3124
3125#if 0
3126 ret = socket_local_server (SOCKET_NAME_RIL,
3127 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
3128
3129 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003130 RLOGE("Unable to bind socket errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003131 exit (-1);
3132 }
3133 s_fdListen = ret;
3134
3135#else
3136 s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);
3137 if (s_fdListen < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003138 RLOGE("Failed to get socket '" SOCKET_NAME_RIL "'");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003139 exit(-1);
3140 }
3141
3142 ret = listen(s_fdListen, 4);
3143
3144 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003145 RLOGE("Failed to listen on control socket '%d': %s",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003146 s_fdListen, strerror(errno));
3147 exit(-1);
3148 }
3149#endif
3150
3151
3152 /* note: non-persistent so we can accept only one connection at a time */
3153 ril_event_set (&s_listen_event, s_fdListen, false,
3154 listenCallback, NULL);
3155
3156 rilEventAddWakeup (&s_listen_event);
3157
3158#if 1
3159 // start debug interface socket
3160
3161 s_fdDebug = android_get_control_socket(SOCKET_NAME_RIL_DEBUG);
3162 if (s_fdDebug < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003163 RLOGE("Failed to get socket '" SOCKET_NAME_RIL_DEBUG "' errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003164 exit(-1);
3165 }
3166
3167 ret = listen(s_fdDebug, 4);
3168
3169 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003170 RLOGE("Failed to listen on ril debug socket '%d': %s",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003171 s_fdDebug, strerror(errno));
3172 exit(-1);
3173 }
3174
3175 ril_event_set (&s_debug_event, s_fdDebug, true,
3176 debugCallback, NULL);
3177
3178 rilEventAddWakeup (&s_debug_event);
3179#endif
3180
3181}
3182
3183static int
3184checkAndDequeueRequestInfo(struct RequestInfo *pRI) {
3185 int ret = 0;
3186
3187 if (pRI == NULL) {
3188 return 0;
3189 }
3190
3191 pthread_mutex_lock(&s_pendingRequestsMutex);
3192
3193 for(RequestInfo **ppCur = &s_pendingRequests
3194 ; *ppCur != NULL
3195 ; ppCur = &((*ppCur)->p_next)
3196 ) {
3197 if (pRI == *ppCur) {
3198 ret = 1;
3199
3200 *ppCur = (*ppCur)->p_next;
3201 break;
3202 }
3203 }
3204
3205 pthread_mutex_unlock(&s_pendingRequestsMutex);
3206
3207 return ret;
3208}
3209
3210
3211extern "C" void
3212RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
3213 RequestInfo *pRI;
3214 int ret;
3215 size_t errorOffset;
3216
3217 pRI = (RequestInfo *)t;
3218
3219 if (!checkAndDequeueRequestInfo(pRI)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003220 RLOGE ("RIL_onRequestComplete: invalid RIL_Token");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003221 return;
3222 }
3223
3224 if (pRI->local > 0) {
3225 // Locally issued command...void only!
3226 // response does not go back up the command socket
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003227 RLOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003228
3229 goto done;
3230 }
3231
3232 appendPrintBuf("[%04d]< %s",
3233 pRI->token, requestToString(pRI->pCI->requestNumber));
3234
3235 if (pRI->cancelled == 0) {
3236 Parcel p;
3237
3238 p.writeInt32 (RESPONSE_SOLICITED);
3239 p.writeInt32 (pRI->token);
3240 errorOffset = p.dataPosition();
3241
3242 p.writeInt32 (e);
3243
3244 if (response != NULL) {
3245 // there is a response payload, no matter success or not.
3246 ret = pRI->pCI->responseFunction(p, response, responselen);
3247
3248 /* if an error occurred, rewind and mark it */
3249 if (ret != 0) {
3250 p.setDataPosition(errorOffset);
3251 p.writeInt32 (ret);
3252 }
3253 }
3254
3255 if (e != RIL_E_SUCCESS) {
3256 appendPrintBuf("%s fails by %s", printBuf, failCauseToString(e));
3257 }
3258
3259 if (s_fdCommand < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003260 RLOGD ("RIL onRequestComplete: Command channel closed");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003261 }
3262 sendResponse(p);
3263 }
3264
3265done:
3266 free(pRI);
3267}
3268
3269
3270static void
3271grabPartialWakeLock() {
3272 acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
3273}
3274
3275static void
3276releaseWakeLock() {
3277 release_wake_lock(ANDROID_WAKE_LOCK_NAME);
3278}
3279
3280/**
3281 * Timer callback to put us back to sleep before the default timeout
3282 */
3283static void
3284wakeTimeoutCallback (void *param) {
3285 // We're using "param != NULL" as a cancellation mechanism
3286 if (param == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003287 //RLOGD("wakeTimeout: releasing wake lock");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003288
3289 releaseWakeLock();
3290 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003291 //RLOGD("wakeTimeout: releasing wake lock CANCELLED");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003292 }
3293}
3294
3295static int
3296decodeVoiceRadioTechnology (RIL_RadioState radioState) {
3297 switch (radioState) {
3298 case RADIO_STATE_SIM_NOT_READY:
3299 case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
3300 case RADIO_STATE_SIM_READY:
3301 return RADIO_TECH_UMTS;
3302
3303 case RADIO_STATE_RUIM_NOT_READY:
3304 case RADIO_STATE_RUIM_READY:
3305 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
3306 case RADIO_STATE_NV_NOT_READY:
3307 case RADIO_STATE_NV_READY:
3308 return RADIO_TECH_1xRTT;
3309
3310 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003311 RLOGD("decodeVoiceRadioTechnology: Invoked with incorrect RadioState");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003312 return -1;
3313 }
3314}
3315
3316static int
3317decodeCdmaSubscriptionSource (RIL_RadioState radioState) {
3318 switch (radioState) {
3319 case RADIO_STATE_SIM_NOT_READY:
3320 case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
3321 case RADIO_STATE_SIM_READY:
3322 case RADIO_STATE_RUIM_NOT_READY:
3323 case RADIO_STATE_RUIM_READY:
3324 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
3325 return CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM;
3326
3327 case RADIO_STATE_NV_NOT_READY:
3328 case RADIO_STATE_NV_READY:
3329 return CDMA_SUBSCRIPTION_SOURCE_NV;
3330
3331 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003332 RLOGD("decodeCdmaSubscriptionSource: Invoked with incorrect RadioState");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003333 return -1;
3334 }
3335}
3336
3337static int
3338decodeSimStatus (RIL_RadioState radioState) {
3339 switch (radioState) {
3340 case RADIO_STATE_SIM_NOT_READY:
3341 case RADIO_STATE_RUIM_NOT_READY:
3342 case RADIO_STATE_NV_NOT_READY:
3343 case RADIO_STATE_NV_READY:
3344 return -1;
3345 case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
3346 case RADIO_STATE_SIM_READY:
3347 case RADIO_STATE_RUIM_READY:
3348 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
3349 return radioState;
3350 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003351 RLOGD("decodeSimStatus: Invoked with incorrect RadioState");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003352 return -1;
3353 }
3354}
3355
3356static bool is3gpp2(int radioTech) {
3357 switch (radioTech) {
3358 case RADIO_TECH_IS95A:
3359 case RADIO_TECH_IS95B:
3360 case RADIO_TECH_1xRTT:
3361 case RADIO_TECH_EVDO_0:
3362 case RADIO_TECH_EVDO_A:
3363 case RADIO_TECH_EVDO_B:
3364 case RADIO_TECH_EHRPD:
3365 return true;
3366 default:
3367 return false;
3368 }
3369}
3370
3371/* If RIL sends SIM states or RUIM states, store the voice radio
3372 * technology and subscription source information so that they can be
3373 * returned when telephony framework requests them
3374 */
3375static RIL_RadioState
3376processRadioState(RIL_RadioState newRadioState) {
3377
3378 if((newRadioState > RADIO_STATE_UNAVAILABLE) && (newRadioState < RADIO_STATE_ON)) {
3379 int newVoiceRadioTech;
3380 int newCdmaSubscriptionSource;
3381 int newSimStatus;
3382
3383 /* This is old RIL. Decode Subscription source and Voice Radio Technology
3384 from Radio State and send change notifications if there has been a change */
3385 newVoiceRadioTech = decodeVoiceRadioTechnology(newRadioState);
3386 if(newVoiceRadioTech != voiceRadioTech) {
3387 voiceRadioTech = newVoiceRadioTech;
3388 RIL_onUnsolicitedResponse (RIL_UNSOL_VOICE_RADIO_TECH_CHANGED,
3389 &voiceRadioTech, sizeof(voiceRadioTech));
3390 }
3391 if(is3gpp2(newVoiceRadioTech)) {
3392 newCdmaSubscriptionSource = decodeCdmaSubscriptionSource(newRadioState);
3393 if(newCdmaSubscriptionSource != cdmaSubscriptionSource) {
3394 cdmaSubscriptionSource = newCdmaSubscriptionSource;
3395 RIL_onUnsolicitedResponse (RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED,
3396 &cdmaSubscriptionSource, sizeof(cdmaSubscriptionSource));
3397 }
3398 }
3399 newSimStatus = decodeSimStatus(newRadioState);
3400 if(newSimStatus != simRuimStatus) {
3401 simRuimStatus = newSimStatus;
3402 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
3403 }
3404
3405 /* Send RADIO_ON to telephony */
3406 newRadioState = RADIO_STATE_ON;
3407 }
3408
3409 return newRadioState;
3410}
3411
3412extern "C"
3413void RIL_onUnsolicitedResponse(int unsolResponse, void *data,
3414 size_t datalen)
3415{
3416 int unsolResponseIndex;
3417 int ret;
3418 int64_t timeReceived = 0;
3419 bool shouldScheduleTimeout = false;
3420 RIL_RadioState newState;
3421
3422 if (s_registerCalled == 0) {
3423 // Ignore RIL_onUnsolicitedResponse before RIL_register
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003424 RLOGW("RIL_onUnsolicitedResponse called before RIL_register");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003425 return;
3426 }
3427
3428 unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
3429
3430 if ((unsolResponseIndex < 0)
3431 || (unsolResponseIndex >= (int32_t)NUM_ELEMS(s_unsolResponses))) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003432 RLOGE("unsupported unsolicited response code %d", unsolResponse);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003433 return;
3434 }
3435
3436 // Grab a wake lock if needed for this reponse,
3437 // as we exit we'll either release it immediately
3438 // or set a timer to release it later.
3439 switch (s_unsolResponses[unsolResponseIndex].wakeType) {
3440 case WAKE_PARTIAL:
3441 grabPartialWakeLock();
3442 shouldScheduleTimeout = true;
3443 break;
3444
3445 case DONT_WAKE:
3446 default:
3447 // No wake lock is grabed so don't set timeout
3448 shouldScheduleTimeout = false;
3449 break;
3450 }
3451
3452 // Mark the time this was received, doing this
3453 // after grabing the wakelock incase getting
3454 // the elapsedRealTime might cause us to goto
3455 // sleep.
3456 if (unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
3457 timeReceived = elapsedRealtime();
3458 }
3459
3460 appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
3461
3462 Parcel p;
3463
3464 p.writeInt32 (RESPONSE_UNSOLICITED);
3465 p.writeInt32 (unsolResponse);
3466
3467 ret = s_unsolResponses[unsolResponseIndex]
3468 .responseFunction(p, data, datalen);
3469 if (ret != 0) {
3470 // Problem with the response. Don't continue;
3471 goto error_exit;
3472 }
3473
3474 // some things get more payload
3475 switch(unsolResponse) {
3476 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
3477 newState = processRadioState(s_callbacks.onStateRequest());
3478 p.writeInt32(newState);
3479 appendPrintBuf("%s {%s}", printBuf,
3480 radioStateToString(s_callbacks.onStateRequest()));
3481 break;
3482
3483
3484 case RIL_UNSOL_NITZ_TIME_RECEIVED:
3485 // Store the time that this was received so the
3486 // handler of this message can account for
3487 // the time it takes to arrive and process. In
3488 // particular the system has been known to sleep
3489 // before this message can be processed.
3490 p.writeInt64(timeReceived);
3491 break;
3492 }
3493
3494 ret = sendResponse(p);
3495 if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
3496
3497 // Unfortunately, NITZ time is not poll/update like everything
3498 // else in the system. So, if the upstream client isn't connected,
3499 // keep a copy of the last NITZ response (with receive time noted
3500 // above) around so we can deliver it when it is connected
3501
3502 if (s_lastNITZTimeData != NULL) {
3503 free (s_lastNITZTimeData);
3504 s_lastNITZTimeData = NULL;
3505 }
3506
3507 s_lastNITZTimeData = malloc(p.dataSize());
3508 s_lastNITZTimeDataSize = p.dataSize();
3509 memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
3510 }
3511
3512 // For now, we automatically go back to sleep after TIMEVAL_WAKE_TIMEOUT
3513 // FIXME The java code should handshake here to release wake lock
3514
3515 if (shouldScheduleTimeout) {
3516 // Cancel the previous request
3517 if (s_last_wake_timeout_info != NULL) {
3518 s_last_wake_timeout_info->userParam = (void *)1;
3519 }
3520
3521 s_last_wake_timeout_info
3522 = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
3523 &TIMEVAL_WAKE_TIMEOUT);
3524 }
3525
3526 // Normal exit
3527 return;
3528
3529error_exit:
3530 if (shouldScheduleTimeout) {
3531 releaseWakeLock();
3532 }
3533}
3534
3535/** FIXME generalize this if you track UserCAllbackInfo, clear it
3536 when the callback occurs
3537*/
3538static UserCallbackInfo *
3539internalRequestTimedCallback (RIL_TimedCallback callback, void *param,
3540 const struct timeval *relativeTime)
3541{
3542 struct timeval myRelativeTime;
3543 UserCallbackInfo *p_info;
3544
3545 p_info = (UserCallbackInfo *) malloc (sizeof(UserCallbackInfo));
3546
3547 p_info->p_callback = callback;
3548 p_info->userParam = param;
3549
3550 if (relativeTime == NULL) {
3551 /* treat null parameter as a 0 relative time */
3552 memset (&myRelativeTime, 0, sizeof(myRelativeTime));
3553 } else {
3554 /* FIXME I think event_add's tv param is really const anyway */
3555 memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime));
3556 }
3557
3558 ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info);
3559
3560 ril_timer_add(&(p_info->event), &myRelativeTime);
3561
3562 triggerEvLoop();
3563 return p_info;
3564}
3565
3566
3567extern "C" void
3568RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
3569 const struct timeval *relativeTime) {
3570 internalRequestTimedCallback (callback, param, relativeTime);
3571}
3572
3573const char *
3574failCauseToString(RIL_Errno e) {
3575 switch(e) {
3576 case RIL_E_SUCCESS: return "E_SUCCESS";
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003577 case RIL_E_RADIO_NOT_AVAILABLE: return "E_RADIO_NOT_AVAILABLE";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003578 case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE";
3579 case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT";
3580 case RIL_E_SIM_PIN2: return "E_SIM_PIN2";
3581 case RIL_E_SIM_PUK2: return "E_SIM_PUK2";
3582 case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED";
3583 case RIL_E_CANCELLED: return "E_CANCELLED";
3584 case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL";
3585 case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW";
3586 case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY";
3587 case RIL_E_SIM_ABSENT:return "E_SIM_ABSENT";
3588 case RIL_E_ILLEGAL_SIM_OR_ME:return "E_ILLEGAL_SIM_OR_ME";
3589#ifdef FEATURE_MULTIMODE_ANDROID
3590 case RIL_E_SUBSCRIPTION_NOT_AVAILABLE:return "E_SUBSCRIPTION_NOT_AVAILABLE";
3591 case RIL_E_MODE_NOT_SUPPORTED:return "E_MODE_NOT_SUPPORTED";
3592#endif
3593 default: return "<unknown error>";
3594 }
3595}
3596
3597const char *
3598radioStateToString(RIL_RadioState s) {
3599 switch(s) {
3600 case RADIO_STATE_OFF: return "RADIO_OFF";
3601 case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE";
3602 case RADIO_STATE_SIM_NOT_READY: return "RADIO_SIM_NOT_READY";
3603 case RADIO_STATE_SIM_LOCKED_OR_ABSENT: return "RADIO_SIM_LOCKED_OR_ABSENT";
3604 case RADIO_STATE_SIM_READY: return "RADIO_SIM_READY";
3605 case RADIO_STATE_RUIM_NOT_READY:return"RADIO_RUIM_NOT_READY";
3606 case RADIO_STATE_RUIM_READY:return"RADIO_RUIM_READY";
3607 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:return"RADIO_RUIM_LOCKED_OR_ABSENT";
3608 case RADIO_STATE_NV_NOT_READY:return"RADIO_NV_NOT_READY";
3609 case RADIO_STATE_NV_READY:return"RADIO_NV_READY";
3610 case RADIO_STATE_ON:return"RADIO_ON";
3611 default: return "<unknown state>";
3612 }
3613}
3614
3615const char *
3616callStateToString(RIL_CallState s) {
3617 switch(s) {
3618 case RIL_CALL_ACTIVE : return "ACTIVE";
3619 case RIL_CALL_HOLDING: return "HOLDING";
3620 case RIL_CALL_DIALING: return "DIALING";
3621 case RIL_CALL_ALERTING: return "ALERTING";
3622 case RIL_CALL_INCOMING: return "INCOMING";
3623 case RIL_CALL_WAITING: return "WAITING";
3624 default: return "<unknown state>";
3625 }
3626}
3627
3628const char *
3629requestToString(int request) {
3630/*
3631 cat libs/telephony/ril_commands.h \
3632 | egrep "^ *{RIL_" \
3633 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
3634
3635
3636 cat libs/telephony/ril_unsol_commands.h \
3637 | egrep "^ *{RIL_" \
3638 | sed -re 's/\{RIL_([^,]+),([^}]+).+/case RIL_\1: return "\1";/'
3639
3640*/
3641 switch(request) {
3642 case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
3643 case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
3644 case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
3645 case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
3646 case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
3647 case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
3648 case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
3649 case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
3650 case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
3651 case RIL_REQUEST_DIAL: return "DIAL";
3652 case RIL_REQUEST_DIAL_EMERGENCY: return "DIAL";
3653 case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
3654 case RIL_REQUEST_HANGUP: return "HANGUP";
3655 case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
3656 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
3657 case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
3658 case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
3659 case RIL_REQUEST_UDUB: return "UDUB";
3660 case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
3661 case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
3662 case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
3663 case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
3664 case RIL_REQUEST_OPERATOR: return "OPERATOR";
3665 case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
3666 case RIL_REQUEST_DTMF: return "DTMF";
3667 case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
3668 case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
3669 case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
3670 case RIL_REQUEST_SIM_IO: return "SIM_IO";
3671 case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
3672 case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
3673 case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
3674 case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
3675 case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
3676 case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
3677 case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
3678 case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
3679 case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
3680 case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
3681 case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
3682 case RIL_REQUEST_ANSWER: return "ANSWER";
3683 case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
3684 case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
3685 case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
3686 case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
3687 case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
3688 case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
3689 case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
3690 case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
3691 case RIL_REQUEST_DTMF_START: return "DTMF_START";
3692 case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
3693 case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
3694 case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
3695 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE";
3696 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE";
3697 case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS";
3698 case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
3699 case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
3700 case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
3701 case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
3702 case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
3703 case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
3704 case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
3705 case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
3706 case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
3707 case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
3708 case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE";
3709 case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE";
3710 case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND";
3711 case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE";
3712 case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
3713 case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
3714 case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER";
3715 case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES";
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003716 case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:return"CDMA_SET_SUBSCRIPTION_SOURCE";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003717 case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:return"CDMA_SET_ROAMING_PREFERENCE";
3718 case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:return"CDMA_QUERY_ROAMING_PREFERENCE";
3719 case RIL_REQUEST_SET_TTY_MODE:return"SET_TTY_MODE";
3720 case RIL_REQUEST_QUERY_TTY_MODE:return"QUERY_TTY_MODE";
3721 case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
3722 case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
3723 case RIL_REQUEST_CDMA_FLASH:return"CDMA_FLASH";
3724 case RIL_REQUEST_CDMA_BURST_DTMF:return"CDMA_BURST_DTMF";
3725 case RIL_REQUEST_CDMA_SEND_SMS:return"CDMA_SEND_SMS";
3726 case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:return"CDMA_SMS_ACKNOWLEDGE";
3727 case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG:return"GSM_GET_BROADCAST_SMS_CONFIG";
3728 case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG:return"GSM_SET_BROADCAST_SMS_CONFIG";
3729 case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG:return "CDMA_GET_BROADCAST_SMS_CONFIG";
3730 case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG:return "CDMA_SET_BROADCAST_SMS_CONFIG";
3731 case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION:return "CDMA_SMS_BROADCAST_ACTIVATION";
Ethan Chend6e30652013-08-04 22:49:56 -07003732 case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return"CDMA_VALIDATE_AND_WRITE_AKEY";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003733 case RIL_REQUEST_CDMA_SUBSCRIPTION: return"CDMA_SUBSCRIPTION";
3734 case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "CDMA_WRITE_SMS_TO_RUIM";
3735 case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "CDMA_DELETE_SMS_ON_RUIM";
3736 case RIL_REQUEST_DEVICE_IDENTITY: return "DEVICE_IDENTITY";
3737 case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "EXIT_EMERGENCY_CALLBACK_MODE";
3738 case RIL_REQUEST_GET_SMSC_ADDRESS: return "GET_SMSC_ADDRESS";
3739 case RIL_REQUEST_SET_SMSC_ADDRESS: return "SET_SMSC_ADDRESS";
3740 case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "REPORT_SMS_MEMORY_STATUS";
3741 case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "REPORT_STK_SERVICE_IS_RUNNING";
3742 case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "CDMA_GET_SUBSCRIPTION_SOURCE";
3743 case RIL_REQUEST_ISIM_AUTHENTICATION: return "ISIM_AUTHENTICATION";
3744 case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
3745 case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
3746 case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH";
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003747 case RIL_REQUEST_GET_CELL_INFO_LIST: return"GET_CELL_INFO_LIST";
3748 case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return"SET_UNSOL_CELL_INFO_LIST_RATE";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003749 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
3750 case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
3751 case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
3752 case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
3753 case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
3754 case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
3755 case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
3756 case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
3757 case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
3758 case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
3759 case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
3760 case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
3761 case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
3762 case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
3763 case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FUL";
3764 case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
3765 case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
3766 case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
3767 case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
3768 case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_NEW_CDMA_SMS";
3769 case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_NEW_BROADCAST_SMS";
3770 case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
3771 case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
3772 case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
3773 case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
3774 case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
3775 case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
3776 case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
3777 case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONE";
3778 case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
3779 case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED";
3780 case RIL_UNSOL_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
3781 case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
3782 case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
3783 case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED";
Ethan Chend6e30652013-08-04 22:49:56 -07003784 case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003785 default: return "<unknown request>";
3786 }
3787}
3788
3789} /* namespace android */