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