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