blob: 54ee61f74fb97f903cbc2a1517f71c897843a878 [file] [log] [blame]
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001/* //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>
Wink Savillef4c4d362009-04-02 01:37:03 -070023#include <telephony/ril_cdma_sms.h>
The Android Open Source Project00f06fc2009-03-03 19:32:15 -080024#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 <utils/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
Wink Savillef4c4d362009-04-02 01:37:03 -070076#define MIN(a,b) ((a)<(b) ? (a) : (b))
77
The Android Open Source Project00f06fc2009-03-03 19:32:15 -080078/* 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 LOGD("[%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 LOGD("%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
Wink Savillef4c4d362009-04-02 01:37:03 -0700205static void dispatchCdmaSms(Parcel &p, RequestInfo *pRI);
206static void dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI);
207static void dispatchBrSmsCnf(Parcel &p, RequestInfo *pRI);
208static void dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI);
209static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI);
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800210static int responseInts(Parcel &p, void *response, size_t responselen);
211static int responseStrings(Parcel &p, void *response, size_t responselen);
212static int responseString(Parcel &p, void *response, size_t responselen);
213static int responseVoid(Parcel &p, void *response, size_t responselen);
214static int responseCallList(Parcel &p, void *response, size_t responselen);
215static int responseSMS(Parcel &p, void *response, size_t responselen);
216static int responseSIM_IO(Parcel &p, void *response, size_t responselen);
217static int responseCallForwards(Parcel &p, void *response, size_t responselen);
Wink Savillef4c4d362009-04-02 01:37:03 -0700218static int responseDataCallList(Parcel &p, void *response, size_t responselen);
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800219static int responseRaw(Parcel &p, void *response, size_t responselen);
220static int responseSsn(Parcel &p, void *response, size_t responselen);
Wink Savillef4c4d362009-04-02 01:37:03 -0700221static int responseSimStatus(Parcel &p, void *response, size_t responselen);
222static int responseBrSmsCnf(Parcel &p, void *response, size_t responselen);
223static int responseCdmaBrCnf(Parcel &p, void *response, size_t responselen);
224static int responseCdmaSms(Parcel &p, void *response, size_t responselen);
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800225static int responseCellList(Parcel &p, void *response, size_t responselen);
226
227extern "C" const char * requestToString(int request);
228extern "C" const char * failCauseToString(RIL_Errno);
229extern "C" const char * callStateToString(RIL_CallState);
230extern "C" const char * radioStateToString(RIL_RadioState);
231
232#ifdef RIL_SHLIB
233extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, void *data,
234 size_t datalen);
235#endif
236
237static UserCallbackInfo * internalRequestTimedCallback
238 (RIL_TimedCallback callback, void *param,
239 const struct timeval *relativeTime);
240
241/** Index == requestNumber */
242static CommandInfo s_commands[] = {
243#include "ril_commands.h"
244};
245
246static UnsolResponseInfo s_unsolResponses[] = {
247#include "ril_unsol_commands.h"
248};
249
250
251static char *
Wink Savillef4c4d362009-04-02 01:37:03 -0700252strdupReadString(Parcel &p) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800253 size_t stringlen;
254 const char16_t *s16;
255
256 s16 = p.readString16Inplace(&stringlen);
257
258 return strndup16to8(s16, stringlen);
259}
260
Wink Savillef4c4d362009-04-02 01:37:03 -0700261static void writeStringToParcel(Parcel &p, const char *s) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800262 char16_t *s16;
263 size_t s16_len;
264 s16 = strdup8to16(s, &s16_len);
265 p.writeString16(s16, s16_len);
266 free(s16);
267}
268
269
270static void
Wink Savillef4c4d362009-04-02 01:37:03 -0700271memsetString (char *s) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800272 if (s != NULL) {
273 memset (s, 0, strlen(s));
274 }
275}
276
277void nullParcelReleaseFunction (const uint8_t* data, size_t dataSize,
278 const size_t* objects, size_t objectsSize,
Wink Savillef4c4d362009-04-02 01:37:03 -0700279 void* cookie) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800280 // do nothing -- the data reference lives longer than the Parcel object
281}
282
283/**
284 * To be called from dispatch thread
285 * Issue a single local request, ensuring that the response
286 * is not sent back up to the command process
287 */
288static void
Wink Savillef4c4d362009-04-02 01:37:03 -0700289issueLocalRequest(int request, void *data, int len) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800290 RequestInfo *pRI;
291 int ret;
292
293 pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
294
295 pRI->local = 1;
296 pRI->token = 0xffffffff; // token is not used in this context
297 pRI->pCI = &(s_commands[request]);
298
299 ret = pthread_mutex_lock(&s_pendingRequestsMutex);
300 assert (ret == 0);
301
302 pRI->p_next = s_pendingRequests;
303 s_pendingRequests = pRI;
304
305 ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
306 assert (ret == 0);
307
308 LOGD("C[locl]> %s", requestToString(request));
309
310 s_callbacks.onRequest(request, data, len, pRI);
311}
312
313
314
315static int
Wink Savillef4c4d362009-04-02 01:37:03 -0700316processCommandBuffer(void *buffer, size_t buflen) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800317 Parcel p;
318 status_t status;
319 int32_t request;
320 int32_t token;
321 RequestInfo *pRI;
322 int ret;
323
324 p.setData((uint8_t *) buffer, buflen);
325
326 // status checked at end
327 status = p.readInt32(&request);
328 status = p.readInt32 (&token);
329
330 if (status != NO_ERROR) {
331 LOGE("invalid request block");
332 return 0;
333 }
334
335 if (request < 1 || request >= (int32_t)NUM_ELEMS(s_commands)) {
336 LOGE("unsupported request code %d token %d", request, token);
337 // FIXME this should perhaps return a response
338 return 0;
339 }
340
341
342 pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
343
344 pRI->token = token;
345 pRI->pCI = &(s_commands[request]);
346
347 ret = pthread_mutex_lock(&s_pendingRequestsMutex);
348 assert (ret == 0);
349
350 pRI->p_next = s_pendingRequests;
351 s_pendingRequests = pRI;
352
353 ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
354 assert (ret == 0);
355
356/* sLastDispatchedToken = token; */
357
358 pRI->pCI->dispatchFunction(p, pRI);
359
360 return 0;
361}
362
363static void
Wink Savillef4c4d362009-04-02 01:37:03 -0700364invalidCommandBlock (RequestInfo *pRI) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800365 LOGE("invalid command block for token %d request %s",
366 pRI->token, requestToString(pRI->pCI->requestNumber));
367}
368
369/** Callee expects NULL */
370static void
Wink Savillef4c4d362009-04-02 01:37:03 -0700371dispatchVoid (Parcel& p, RequestInfo *pRI) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800372 clearPrintBuf;
373 printRequest(pRI->token, pRI->pCI->requestNumber);
374 s_callbacks.onRequest(pRI->pCI->requestNumber, NULL, 0, pRI);
375}
376
377/** Callee expects const char * */
378static void
Wink Savillef4c4d362009-04-02 01:37:03 -0700379dispatchString (Parcel& p, RequestInfo *pRI) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800380 status_t status;
381 size_t datalen;
382 size_t stringlen;
383 char *string8 = NULL;
384
385 string8 = strdupReadString(p);
386
387 startRequest;
388 appendPrintBuf("%s%s", printBuf, string8);
389 closeRequest;
390 printRequest(pRI->token, pRI->pCI->requestNumber);
391
392 s_callbacks.onRequest(pRI->pCI->requestNumber, string8,
393 sizeof(char *), pRI);
394
395#ifdef MEMSET_FREED
396 memsetString(string8);
397#endif
398
399 free(string8);
400 return;
401invalid:
402 invalidCommandBlock(pRI);
403 return;
404}
405
406/** Callee expects const char ** */
407static void
Wink Savillef4c4d362009-04-02 01:37:03 -0700408dispatchStrings (Parcel &p, RequestInfo *pRI) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800409 int32_t countStrings;
410 status_t status;
411 size_t datalen;
412 char **pStrings;
413
414 status = p.readInt32 (&countStrings);
415
416 if (status != NO_ERROR) {
417 goto invalid;
418 }
419
420 startRequest;
421 if (countStrings == 0) {
422 // just some non-null pointer
423 pStrings = (char **)alloca(sizeof(char *));
424 datalen = 0;
425 } else if (((int)countStrings) == -1) {
426 pStrings = NULL;
427 datalen = 0;
428 } else {
429 datalen = sizeof(char *) * countStrings;
430
431 pStrings = (char **)alloca(datalen);
432
433 for (int i = 0 ; i < countStrings ; i++) {
434 pStrings[i] = strdupReadString(p);
435 appendPrintBuf("%s%s,", printBuf, pStrings[i]);
436 }
437 }
438 removeLastChar;
439 closeRequest;
440 printRequest(pRI->token, pRI->pCI->requestNumber);
441
442 s_callbacks.onRequest(pRI->pCI->requestNumber, pStrings, datalen, pRI);
443
444 if (pStrings != NULL) {
445 for (int i = 0 ; i < countStrings ; i++) {
446#ifdef MEMSET_FREED
447 memsetString (pStrings[i]);
448#endif
449 free(pStrings[i]);
450 }
451
452#ifdef MEMSET_FREED
453 memset(pStrings, 0, datalen);
454#endif
455 }
456
457 return;
458invalid:
459 invalidCommandBlock(pRI);
460 return;
461}
462
463/** Callee expects const int * */
464static void
Wink Savillef4c4d362009-04-02 01:37:03 -0700465dispatchInts (Parcel &p, RequestInfo *pRI) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800466 int32_t count;
467 status_t status;
468 size_t datalen;
469 int *pInts;
470
471 status = p.readInt32 (&count);
472
473 if (status != NO_ERROR || count == 0) {
474 goto invalid;
475 }
476
477 datalen = sizeof(int) * count;
478 pInts = (int *)alloca(datalen);
479
480 startRequest;
481 for (int i = 0 ; i < count ; i++) {
482 int32_t t;
483
484 status = p.readInt32(&t);
485 pInts[i] = (int)t;
486 appendPrintBuf("%s%d,", printBuf, t);
487
488 if (status != NO_ERROR) {
489 goto invalid;
490 }
491 }
492 removeLastChar;
493 closeRequest;
494 printRequest(pRI->token, pRI->pCI->requestNumber);
495
496 s_callbacks.onRequest(pRI->pCI->requestNumber, const_cast<int *>(pInts),
497 datalen, pRI);
498
499#ifdef MEMSET_FREED
500 memset(pInts, 0, datalen);
501#endif
502
503 return;
504invalid:
505 invalidCommandBlock(pRI);
506 return;
507}
508
509
510/**
511 * Callee expects const RIL_SMS_WriteArgs *
512 * Payload is:
513 * int32_t status
514 * String pdu
515 */
516static void
Wink Savillef4c4d362009-04-02 01:37:03 -0700517dispatchSmsWrite (Parcel &p, RequestInfo *pRI) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800518 RIL_SMS_WriteArgs args;
519 int32_t t;
520 status_t status;
521
522 memset (&args, 0, sizeof(args));
523
524 status = p.readInt32(&t);
525 args.status = (int)t;
526
527 args.pdu = strdupReadString(p);
528
529 if (status != NO_ERROR || args.pdu == NULL) {
530 goto invalid;
531 }
532
533 args.smsc = strdupReadString(p);
534
535 startRequest;
536 appendPrintBuf("%s%d,%s,smsc=%s", printBuf, args.status,
537 (char*)args.pdu, (char*)args.smsc);
538 closeRequest;
539 printRequest(pRI->token, pRI->pCI->requestNumber);
540
541 s_callbacks.onRequest(pRI->pCI->requestNumber, &args, sizeof(args), pRI);
542
543#ifdef MEMSET_FREED
544 memsetString (args.pdu);
545#endif
546
547 free (args.pdu);
548
549#ifdef MEMSET_FREED
550 memset(&args, 0, sizeof(args));
551#endif
552
553 return;
554invalid:
555 invalidCommandBlock(pRI);
556 return;
557}
558
559/**
560 * Callee expects const RIL_Dial *
561 * Payload is:
562 * String address
563 * int32_t clir
564 */
565static void
Wink Savillef4c4d362009-04-02 01:37:03 -0700566dispatchDial (Parcel &p, RequestInfo *pRI) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800567 RIL_Dial dial;
568 int32_t t;
569 status_t status;
570
571 memset (&dial, 0, sizeof(dial));
572
573 dial.address = strdupReadString(p);
574
575 status = p.readInt32(&t);
576 dial.clir = (int)t;
577
578 if (status != NO_ERROR || dial.address == NULL) {
579 goto invalid;
580 }
581
582 startRequest;
583 appendPrintBuf("%snum=%s,clir=%d", printBuf, dial.address, dial.clir);
584 closeRequest;
585 printRequest(pRI->token, pRI->pCI->requestNumber);
586
587 s_callbacks.onRequest(pRI->pCI->requestNumber, &dial, sizeof(dial), pRI);
588
589#ifdef MEMSET_FREED
590 memsetString (dial.address);
591#endif
592
593 free (dial.address);
594
595#ifdef MEMSET_FREED
596 memset(&dial, 0, sizeof(dial));
597#endif
598
599 return;
600invalid:
601 invalidCommandBlock(pRI);
602 return;
603}
604
605/**
606 * Callee expects const RIL_SIM_IO *
607 * Payload is:
608 * int32_t command
609 * int32_t fileid
610 * String path
611 * int32_t p1, p2, p3
612 * String data
613 * String pin2
614 */
615static void
Wink Savillef4c4d362009-04-02 01:37:03 -0700616dispatchSIM_IO (Parcel &p, RequestInfo *pRI) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800617 RIL_SIM_IO simIO;
618 int32_t t;
619 status_t status;
620
621 memset (&simIO, 0, sizeof(simIO));
622
623 // note we only check status at the end
624
625 status = p.readInt32(&t);
626 simIO.command = (int)t;
627
628 status = p.readInt32(&t);
629 simIO.fileid = (int)t;
630
631 simIO.path = strdupReadString(p);
632
633 status = p.readInt32(&t);
634 simIO.p1 = (int)t;
635
636 status = p.readInt32(&t);
637 simIO.p2 = (int)t;
638
639 status = p.readInt32(&t);
640 simIO.p3 = (int)t;
641
642 simIO.data = strdupReadString(p);
643 simIO.pin2 = strdupReadString(p);
644
645 startRequest;
646 appendPrintBuf("%scmd=0x%X,efid=0x%X,path=%s,%d,%d,%d,%s,pin2=%s", printBuf,
647 simIO.command, simIO.fileid, (char*)simIO.path,
648 simIO.p1, simIO.p2, simIO.p3,
649 (char*)simIO.data, (char*)simIO.pin2);
650 closeRequest;
651 printRequest(pRI->token, pRI->pCI->requestNumber);
652
653 if (status != NO_ERROR) {
654 goto invalid;
655 }
656
657 s_callbacks.onRequest(pRI->pCI->requestNumber, &simIO, sizeof(simIO), pRI);
658
659#ifdef MEMSET_FREED
660 memsetString (simIO.path);
661 memsetString (simIO.data);
662 memsetString (simIO.pin2);
663#endif
664
665 free (simIO.path);
666 free (simIO.data);
667 free (simIO.pin2);
668
669#ifdef MEMSET_FREED
670 memset(&simIO, 0, sizeof(simIO));
671#endif
672
673 return;
674invalid:
675 invalidCommandBlock(pRI);
676 return;
677}
678
679/**
680 * Callee expects const RIL_CallForwardInfo *
681 * Payload is:
682 * int32_t status/action
683 * int32_t reason
684 * int32_t serviceCode
685 * int32_t toa
686 * String number (0 length -> null)
687 * int32_t timeSeconds
688 */
689static void
Wink Savillef4c4d362009-04-02 01:37:03 -0700690dispatchCallForward(Parcel &p, RequestInfo *pRI) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800691 RIL_CallForwardInfo cff;
692 int32_t t;
693 status_t status;
694
695 memset (&cff, 0, sizeof(cff));
696
697 // note we only check status at the end
698
699 status = p.readInt32(&t);
700 cff.status = (int)t;
701
702 status = p.readInt32(&t);
703 cff.reason = (int)t;
704
705 status = p.readInt32(&t);
706 cff.serviceClass = (int)t;
707
708 status = p.readInt32(&t);
709 cff.toa = (int)t;
710
711 cff.number = strdupReadString(p);
712
713 status = p.readInt32(&t);
714 cff.timeSeconds = (int)t;
715
716 if (status != NO_ERROR) {
717 goto invalid;
718 }
719
720 // special case: number 0-length fields is null
721
722 if (cff.number != NULL && strlen (cff.number) == 0) {
723 cff.number = NULL;
724 }
725
726 startRequest;
727 appendPrintBuf("%sstat=%d,reason=%d,serv=%d,toa=%d,%s,tout=%d", printBuf,
728 cff.status, cff.reason, cff.serviceClass, cff.toa,
729 (char*)cff.number, cff.timeSeconds);
730 closeRequest;
731 printRequest(pRI->token, pRI->pCI->requestNumber);
732
733 s_callbacks.onRequest(pRI->pCI->requestNumber, &cff, sizeof(cff), pRI);
734
735#ifdef MEMSET_FREED
736 memsetString(cff.number);
737#endif
738
739 free (cff.number);
740
741#ifdef MEMSET_FREED
742 memset(&cff, 0, sizeof(cff));
743#endif
744
745 return;
746invalid:
747 invalidCommandBlock(pRI);
748 return;
749}
750
751
752static void
Wink Savillef4c4d362009-04-02 01:37:03 -0700753dispatchRaw(Parcel &p, RequestInfo *pRI) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -0800754 int32_t len;
755 status_t status;
756 const void *data;
757
758 status = p.readInt32(&len);
759
760 if (status != NO_ERROR) {
761 goto invalid;
762 }
763
764 // The java code writes -1 for null arrays
765 if (((int)len) == -1) {
766 data = NULL;
767 len = 0;
768 }
769
770 data = p.readInplace(len);
771
772 startRequest;
773 appendPrintBuf("%sraw_size=%d", printBuf, len);
774 closeRequest;
775 printRequest(pRI->token, pRI->pCI->requestNumber);
776
777 s_callbacks.onRequest(pRI->pCI->requestNumber, const_cast<void *>(data), len, pRI);
778
779 return;
780invalid:
781 invalidCommandBlock(pRI);
782 return;
783}
784
Wink Savillef4c4d362009-04-02 01:37:03 -0700785static void
786dispatchCdmaSms(Parcel &p, RequestInfo *pRI) {
787 RIL_CDMA_SMS_Message rcsm;
788 int32_t t;
789 uint8_t ut;
790 status_t status;
791 int32_t digitCount;
792 int digitLimit;
793
794 memset(&rcsm, 0, sizeof(rcsm));
795
796 status = p.readInt32(&t);
797 rcsm.uTeleserviceID = (int) t;
798
799 status = p.read(&ut,sizeof(ut));
800 rcsm.bIsServicePresent = (uint8_t) ut;
801
802 status = p.readInt32(&t);
803 rcsm.uServicecategory = (int) t;
804
805 status = p.readInt32(&t);
806 rcsm.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
807
808 status = p.readInt32(&t);
809 rcsm.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
810
811 status = p.readInt32(&t);
812 rcsm.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
813
814 status = p.readInt32(&t);
815 rcsm.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
816
817 status = p.read(&ut,sizeof(ut));
818 rcsm.sAddress.number_of_digits= (uint8_t) ut;
819
820 digitLimit= MIN((rcsm.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
821 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
822 status = p.read(&ut,sizeof(ut));
823 rcsm.sAddress.digits[digitCount] = (uint8_t) ut;
824 }
825
826 status = p.readInt32(&t);
827 rcsm.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
828
829 status = p.read(&ut,sizeof(ut));
830 rcsm.sSubAddress.odd = (uint8_t) ut;
831
832 status = p.read(&ut,sizeof(ut));
833 rcsm.sSubAddress.number_of_digits = (uint8_t) ut;
834
835 digitLimit= MIN((rcsm.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
836 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
837 status = p.read(&ut,sizeof(ut));
838 rcsm.sSubAddress.digits[digitCount] = (uint8_t) ut;
839 }
840
841 status = p.readInt32(&t);
842 rcsm.uBearerDataLen = (int) t;
843
844 digitLimit= MIN((rcsm.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
845 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
846 status = p.read(&ut, sizeof(ut));
847 rcsm.aBearerData[digitCount] = (uint8_t) ut;
848 }
849
850 if (status != NO_ERROR) {
851 goto invalid;
852 }
853
854 startRequest;
855 appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
Wink Saville1b5fd232009-04-22 14:50:00 -0700856 sAddress.digit_mode=%d, sAddress.Number_mode=%d, sAddress.number_type=%d, ",
Wink Savillef4c4d362009-04-02 01:37:03 -0700857 printBuf, rcsm.uTeleserviceID,rcsm.bIsServicePresent,rcsm.uServicecategory,
Wink Saville1b5fd232009-04-22 14:50:00 -0700858 rcsm.sAddress.digit_mode, rcsm.sAddress.number_mode,rcsm.sAddress.number_type);
Wink Savillef4c4d362009-04-02 01:37:03 -0700859 closeRequest;
860
861 printRequest(pRI->token, pRI->pCI->requestNumber);
862
863 s_callbacks.onRequest(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm),pRI);
864
865#ifdef MEMSET_FREED
866 memset(&rcsm, 0, sizeof(rcsm));
867#endif
868
869 return;
870
871invalid:
872 invalidCommandBlock(pRI);
873 return;
874}
875
876static void
877dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI) {
878 RIL_CDMA_SMS_Ack rcsa;
879 int32_t t;
880 status_t status;
881 int32_t digitCount;
882
883 memset(&rcsa, 0, sizeof(rcsa));
884
885 status = p.readInt32(&t);
886 rcsa.uErrorClass = (RIL_CDMA_SMS_ErrorClass) t;
887
888 status = p.readInt32(&t);
889 rcsa.uSMSCauseCode = (int) t;
890
891 if (status != NO_ERROR) {
892 goto invalid;
893 }
894
895 startRequest;
Wink Saville1b5fd232009-04-22 14:50:00 -0700896 appendPrintBuf("%suErrorClass=%d, uTLStatus=%d, ",
897 printBuf, rcsa.uErrorClass, rcsa.uSMSCauseCode);
Wink Savillef4c4d362009-04-02 01:37:03 -0700898 closeRequest;
899
900 printRequest(pRI->token, pRI->pCI->requestNumber);
901
902 s_callbacks.onRequest(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa),pRI);
903
904#ifdef MEMSET_FREED
905 memset(&rcsa, 0, sizeof(rcsa));
906#endif
907
908 return;
909
910invalid:
911 invalidCommandBlock(pRI);
912 return;
913}
914
915static void
916dispatchBrSmsCnf(Parcel &p, RequestInfo *pRI) {
917 RIL_BroadcastSMSConfig rbsc;
918 int32_t t;
919 uint8_t ut;
920 status_t status;
921 int32_t digitCount;
922
923 memset(&rbsc, 0, sizeof(rbsc));
924
925 status = p.readInt32(&t);
926 rbsc.size = (int) t;
927
928 status = p.readInt32(&t);
929 rbsc.entries->uFromServiceID = (int) t;
930
931 status = p.readInt32(&t);
932 rbsc.entries->uToserviceID = (int) t;
933
934 //usage of read function on assumption that it reads any length given as 2nd argument
935 status = p.read(&ut,sizeof(ut));
936 rbsc.entries->bSelected = (uint8_t) ut;
937
938 if (status != NO_ERROR) {
939 goto invalid;
940 }
941
942 startRequest;
Wink Saville1b5fd232009-04-22 14:50:00 -0700943 appendPrintBuf("%ssize=%d, entries.uFromServiceID=%d, \
Wink Savillef4c4d362009-04-02 01:37:03 -0700944 entries.uToserviceID=%d, entries.bSelected =%d, ", printBuf,
945 rbsc.size,rbsc.entries->uFromServiceID, rbsc.entries->uToserviceID,
946 rbsc.entries->bSelected);
947 closeRequest;
948
949 printRequest(pRI->token, pRI->pCI->requestNumber);
950
951 s_callbacks.onRequest(pRI->pCI->requestNumber, &rbsc, sizeof(rbsc),pRI);
952
953#ifdef MEMSET_FREED
954 memset(&rbsc, 0, sizeof(rbsc));
955#endif
956
957 return;
958
959invalid:
960 invalidCommandBlock(pRI);
961 return;
962
963}
964
965static void
966dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI) {
967 RIL_CDMA_BroadcastSMSConfig rcbsc;
968 int32_t t;
969 uint8_t ut;
970 status_t status;
971 int32_t digitCount;
972
Wink Savillef4c4d362009-04-02 01:37:03 -0700973 status = p.readInt32(&t);
974 rcbsc.size = (int) t;
975
Wink Savillef5903df2009-04-24 11:54:14 -0700976 LOGE("RIL_CPP: dispatchCdmaBrSmsCnf(), isize=%d", rcbsc.size);
Wink Savillef4c4d362009-04-02 01:37:03 -0700977
Wink Savillef5903df2009-04-24 11:54:14 -0700978 if (rcbsc.size != 0) {
979 RIL_CDMA_BroadcastServiceInfo cdmaBsi[rcbsc.size];
980 for (int i = 0 ; i < rcbsc.size ; i++ ) {
981 status = p.readInt32(&t);
982 cdmaBsi[i].uServiceCategory = (int) t;
Wink Savillef4c4d362009-04-02 01:37:03 -0700983
Wink Savillef5903df2009-04-24 11:54:14 -0700984 status = p.readInt32(&t);
985 cdmaBsi[i].uLanguage = (int) t;
986
987 status = p.readInt32(&t);
988 cdmaBsi[i].bSelected = (uint8_t) t;
989
990 startRequest;
991 appendPrintBuf("%sentries.uServicecategory=%d, entries.uLanguage =%d, \
992 entries.bSelected =%d, ", printBuf, cdmaBsi[i].uServiceCategory,
993 cdmaBsi[i].uLanguage, cdmaBsi[i].bSelected);
994 closeRequest;
995 }
996 rcbsc.entries = (RIL_CDMA_BroadcastServiceInfo *)calloc(rcbsc.size,
997 sizeof(RIL_CDMA_BroadcastServiceInfo));
998 memcpy(rcbsc.entries, cdmaBsi, (sizeof(RIL_CDMA_BroadcastServiceInfo) * rcbsc.size));
999 } else {
1000 rcbsc.entries = NULL;
1001 }
Wink Savillef4c4d362009-04-02 01:37:03 -07001002
1003 if (status != NO_ERROR) {
1004 goto invalid;
1005 }
1006
Wink Savillef5903df2009-04-24 11:54:14 -07001007 s_callbacks.onRequest(pRI->pCI->requestNumber,
1008 &rcbsc,
1009 (sizeof(RIL_CDMA_BroadcastServiceInfo) * rcbsc.size) + sizeof(int),
1010 pRI);
Wink Savillef4c4d362009-04-02 01:37:03 -07001011
1012#ifdef MEMSET_FREED
1013 memset(&rcbsc, 0, sizeof(rcbsc));
1014#endif
1015
1016 return;
1017
1018invalid:
1019 invalidCommandBlock(pRI);
1020 return;
1021
1022}
1023
1024static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI) {
1025 RIL_CDMA_SMS_WriteArgs rcsw;
1026 int32_t t;
1027 uint32_t ut;
1028 uint8_t uct;
1029 status_t status;
1030 int32_t digitCount;
1031
1032 memset(&rcsw, 0, sizeof(rcsw));
1033
1034 status = p.readInt32(&t);
1035 rcsw.status = t;
1036
1037 status = p.readInt32(&t);
1038 rcsw.message.uTeleserviceID = (int) t;
1039
1040 status = p.read(&uct,sizeof(uct));
1041 rcsw.message.bIsServicePresent = (uint8_t) uct;
1042
1043 status = p.readInt32(&t);
1044 rcsw.message.uServicecategory = (int) t;
1045
1046 status = p.readInt32(&t);
1047 rcsw.message.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
1048
1049 status = p.readInt32(&t);
1050 rcsw.message.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
1051
1052 status = p.readInt32(&t);
1053 rcsw.message.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
1054
1055 status = p.readInt32(&t);
1056 rcsw.message.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
1057
1058 status = p.read(&uct,sizeof(uct));
1059 rcsw.message.sAddress.number_of_digits = (uint8_t) uct;
1060
1061 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_ADDRESS_MAX; digitCount ++) {
1062 status = p.read(&uct,sizeof(uct));
1063 rcsw.message.sAddress.digits[digitCount] = (uint8_t) uct;
1064 }
1065
1066 status = p.readInt32(&t);
1067 rcsw.message.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
1068
1069 status = p.read(&uct,sizeof(uct));
1070 rcsw.message.sSubAddress.odd = (uint8_t) uct;
1071
1072 status = p.read(&uct,sizeof(uct));
1073 rcsw.message.sSubAddress.number_of_digits = (uint8_t) uct;
1074
1075 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_SUBADDRESS_MAX; digitCount ++) {
1076 status = p.read(&uct,sizeof(uct));
1077 rcsw.message.sSubAddress.digits[digitCount] = (uint8_t) uct;
1078 }
1079
1080 status = p.readInt32(&t);
1081 rcsw.message.uBearerDataLen = (int) t;
1082
1083 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_BEARER_DATA_MAX; digitCount ++) {
1084 status = p.read(&uct, sizeof(uct));
1085 rcsw.message.aBearerData[digitCount] = (uint8_t) uct;
1086 }
1087
1088 if (status != NO_ERROR) {
1089 goto invalid;
1090 }
1091
1092 startRequest;
Wink Saville1b5fd232009-04-22 14:50:00 -07001093 appendPrintBuf("%sstatus=%d, message.uTeleserviceID=%d, message.bIsServicePresent=%d, \
1094 message.uServicecategory=%d, message.sAddress.digit_mode=%d, \
1095 message.sAddress.number_mode=%d, \
1096 message.sAddress.number_type=%d, ",
Wink Savillef4c4d362009-04-02 01:37:03 -07001097 printBuf, rcsw.status, rcsw.message.uTeleserviceID, rcsw.message.bIsServicePresent,
Wink Saville1b5fd232009-04-22 14:50:00 -07001098 rcsw.message.uServicecategory, rcsw.message.sAddress.digit_mode,
1099 rcsw.message.sAddress.number_mode,
1100 rcsw.message.sAddress.number_type);
Wink Savillef4c4d362009-04-02 01:37:03 -07001101 closeRequest;
1102
1103 printRequest(pRI->token, pRI->pCI->requestNumber);
1104
1105 s_callbacks.onRequest(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw),pRI);
1106
1107#ifdef MEMSET_FREED
1108 memset(&rcsw, 0, sizeof(rcsw));
1109#endif
1110
1111 return;
1112
1113invalid:
1114 invalidCommandBlock(pRI);
1115 return;
1116
1117}
1118
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001119static int
Wink Savillef4c4d362009-04-02 01:37:03 -07001120blockingWrite(int fd, const void *buffer, size_t len) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001121 size_t writeOffset = 0;
1122 const uint8_t *toWrite;
1123
1124 toWrite = (const uint8_t *)buffer;
1125
1126 while (writeOffset < len) {
1127 ssize_t written;
1128 do {
1129 written = write (fd, toWrite + writeOffset,
1130 len - writeOffset);
1131 } while (written < 0 && errno == EINTR);
1132
1133 if (written >= 0) {
1134 writeOffset += written;
1135 } else { // written < 0
1136 LOGE ("RIL Response: unexpected error on write errno:%d", errno);
1137 close(fd);
1138 return -1;
1139 }
1140 }
1141
1142 return 0;
1143}
1144
1145static int
Wink Savillef4c4d362009-04-02 01:37:03 -07001146sendResponseRaw (const void *data, size_t dataSize) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001147 int fd = s_fdCommand;
1148 int ret;
1149 uint32_t header;
1150
1151 if (s_fdCommand < 0) {
1152 return -1;
1153 }
1154
1155 if (dataSize > MAX_COMMAND_BYTES) {
1156 LOGE("RIL: packet larger than %u (%u)",
1157 MAX_COMMAND_BYTES, (unsigned int )dataSize);
1158
1159 return -1;
1160 }
1161
1162
1163 // FIXME is blocking here ok? issue #550970
1164
1165 pthread_mutex_lock(&s_writeMutex);
1166
1167 header = htonl(dataSize);
1168
1169 ret = blockingWrite(fd, (void *)&header, sizeof(header));
1170
1171 if (ret < 0) {
1172 return ret;
1173 }
1174
1175 blockingWrite(fd, data, dataSize);
1176
1177 if (ret < 0) {
1178 return ret;
1179 }
1180
1181 pthread_mutex_unlock(&s_writeMutex);
1182
1183 return 0;
1184}
1185
1186static int
Wink Savillef4c4d362009-04-02 01:37:03 -07001187sendResponse (Parcel &p) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001188 printResponse;
1189 return sendResponseRaw(p.data(), p.dataSize());
1190}
1191
1192/** response is an int* pointing to an array of ints*/
1193
1194static int
Wink Savillef4c4d362009-04-02 01:37:03 -07001195responseInts(Parcel &p, void *response, size_t responselen) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001196 int numInts;
1197
1198 if (response == NULL && responselen != 0) {
1199 LOGE("invalid response: NULL");
1200 return RIL_ERRNO_INVALID_RESPONSE;
1201 }
1202 if (responselen % sizeof(int) != 0) {
1203 LOGE("invalid response length %d expected multiple of %d\n",
1204 (int)responselen, (int)sizeof(int));
1205 return RIL_ERRNO_INVALID_RESPONSE;
1206 }
1207
1208 int *p_int = (int *) response;
1209
1210 numInts = responselen / sizeof(int *);
1211 p.writeInt32 (numInts);
1212
1213 /* each int*/
1214 startResponse;
1215 for (int i = 0 ; i < numInts ; i++) {
1216 appendPrintBuf("%s%d,", printBuf, p_int[i]);
1217 p.writeInt32(p_int[i]);
1218 }
1219 removeLastChar;
1220 closeResponse;
1221
1222 return 0;
1223}
1224
1225/** response is a char **, pointing to an array of char *'s */
Wink Savillef4c4d362009-04-02 01:37:03 -07001226static int responseStrings(Parcel &p, void *response, size_t responselen) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001227 int numStrings;
1228
1229 if (response == NULL && responselen != 0) {
1230 LOGE("invalid response: NULL");
1231 return RIL_ERRNO_INVALID_RESPONSE;
1232 }
1233 if (responselen % sizeof(char *) != 0) {
1234 LOGE("invalid response length %d expected multiple of %d\n",
1235 (int)responselen, (int)sizeof(char *));
1236 return RIL_ERRNO_INVALID_RESPONSE;
1237 }
1238
1239 if (response == NULL) {
1240 p.writeInt32 (0);
1241 } else {
1242 char **p_cur = (char **) response;
1243
1244 numStrings = responselen / sizeof(char *);
1245 p.writeInt32 (numStrings);
1246
1247 /* each string*/
1248 startResponse;
1249 for (int i = 0 ; i < numStrings ; i++) {
1250 appendPrintBuf("%s%s,", printBuf, (char*)p_cur[i]);
1251 writeStringToParcel (p, p_cur[i]);
1252 }
1253 removeLastChar;
1254 closeResponse;
1255 }
1256 return 0;
1257}
1258
1259
1260/**
1261 * NULL strings are accepted
1262 * FIXME currently ignores responselen
1263 */
Wink Savillef4c4d362009-04-02 01:37:03 -07001264static int responseString(Parcel &p, void *response, size_t responselen) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001265 /* one string only */
1266 startResponse;
1267 appendPrintBuf("%s%s", printBuf, (char*)response);
1268 closeResponse;
1269
1270 writeStringToParcel(p, (const char *)response);
1271
1272 return 0;
1273}
1274
Wink Savillef4c4d362009-04-02 01:37:03 -07001275static int responseVoid(Parcel &p, void *response, size_t responselen) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001276 startResponse;
1277 removeLastChar;
1278 return 0;
1279}
1280
Wink Savillef4c4d362009-04-02 01:37:03 -07001281static int responseCallList(Parcel &p, void *response, size_t responselen) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001282 int num;
1283
1284 if (response == NULL && responselen != 0) {
1285 LOGE("invalid response: NULL");
1286 return RIL_ERRNO_INVALID_RESPONSE;
1287 }
1288
1289 if (responselen % sizeof (RIL_Call *) != 0) {
1290 LOGE("invalid response length %d expected multiple of %d\n",
1291 (int)responselen, (int)sizeof (RIL_Call *));
1292 return RIL_ERRNO_INVALID_RESPONSE;
1293 }
1294
1295 startResponse;
1296 /* number of call info's */
1297 num = responselen / sizeof(RIL_Call *);
1298 p.writeInt32(num);
1299
1300 for (int i = 0 ; i < num ; i++) {
Wink Saville1b5fd232009-04-22 14:50:00 -07001301 /* NEWRIL:TODO Remove this conditional and the else clause when we have the new ril */
1302#if NEWRIL
1303 LOGD("Compilied for NEWRIL"); // NEWRIL:TODO remove when we have the new ril
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001304 RIL_Call *p_cur = ((RIL_Call **) response)[i];
1305 /* each call info */
1306 p.writeInt32(p_cur->state);
1307 p.writeInt32(p_cur->index);
1308 p.writeInt32(p_cur->toa);
1309 p.writeInt32(p_cur->isMpty);
1310 p.writeInt32(p_cur->isMT);
1311 p.writeInt32(p_cur->als);
1312 p.writeInt32(p_cur->isVoice);
Wink Saville1b5fd232009-04-22 14:50:00 -07001313 p.writeInt32(p_cur->isVoicePrivacy);
1314 writeStringToParcel(p, p_cur->number);
John Wangff368742009-03-24 17:56:29 -07001315 p.writeInt32(p_cur->numberPresentation);
Wink Saville1b5fd232009-04-22 14:50:00 -07001316 writeStringToParcel(p, p_cur->name);
1317 p.writeInt32(p_cur->namePresentation);
1318 appendPrintBuf("%s[id=%d,%s,toa=%d,%s,%s,als=%d,%s,%s,%s,cli=%d,name='%s',%d],",
John Wangff368742009-03-24 17:56:29 -07001319 printBuf,
Wink Saville1b5fd232009-04-22 14:50:00 -07001320 p_cur->index,
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001321 callStateToString(p_cur->state),
Wink Saville1b5fd232009-04-22 14:50:00 -07001322 p_cur->toa,
1323 (p_cur->isMpty)?"conf":"norm",
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001324 (p_cur->isMT)?"mt":"mo",
1325 p_cur->als,
1326 (p_cur->isVoice)?"voc":"nonvoc",
Wink Saville1b5fd232009-04-22 14:50:00 -07001327 (p_cur->isVoicePrivacy)?"evp":"noevp",
1328 p_cur->number,
1329 p_cur->numberPresentation,
1330 p_cur->name,
1331 p_cur->namePresentation);
1332#else
1333 LOGD("Old RIL");
1334 RIL_CallOld *p_cur = ((RIL_CallOld **) response)[i];
1335 /* each call info */
1336 p.writeInt32(p_cur->state);
1337 p.writeInt32(p_cur->index);
1338 p.writeInt32(p_cur->toa);
1339 p.writeInt32(p_cur->isMpty);
1340 p.writeInt32(p_cur->isMT);
1341 p.writeInt32(p_cur->als);
1342 p.writeInt32(p_cur->isVoice);
1343 p.writeInt32(0); // p_cur->isVoicePrivacy);
1344 writeStringToParcel (p, p_cur->number);
1345 p.writeInt32(p_cur->numberPresentation);
1346 writeStringToParcel (p, "a-person");
1347 p.writeInt32(2); // p_cur->namePresentation);
1348 appendPrintBuf("%s[id=%d,%s,toa=%d,%s,%s,als=%d,%s,%s,%s,cli=%d,name='%s',%d],",
1349 printBuf,
1350 p_cur->index,
1351 callStateToString(p_cur->state),
1352 p_cur->toa,
1353 (p_cur->isMpty)?"conf":"norm",
1354 (p_cur->isMT)?"mt":"mo",
1355 p_cur->als,
1356 (p_cur->isVoice)?"voc":"nonvoc",
1357 (p_cur->isVoicePrivacy)?"evp":"noevp",
1358 p_cur->number,
1359 p_cur->numberPresentation,
1360 p_cur->name,
1361 p_cur->namePresentation);
1362#endif
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001363 }
1364 removeLastChar;
1365 closeResponse;
1366
1367 return 0;
1368}
1369
Wink Savillef4c4d362009-04-02 01:37:03 -07001370static int responseSMS(Parcel &p, void *response, size_t responselen) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001371 if (response == NULL) {
1372 LOGE("invalid response: NULL");
1373 return RIL_ERRNO_INVALID_RESPONSE;
1374 }
1375
1376 if (responselen != sizeof (RIL_SMS_Response) ) {
1377 LOGE("invalid response length %d expected %d",
1378 (int)responselen, (int)sizeof (RIL_SMS_Response));
1379 return RIL_ERRNO_INVALID_RESPONSE;
1380 }
1381
1382 RIL_SMS_Response *p_cur = (RIL_SMS_Response *) response;
1383
1384 p.writeInt32(p_cur->messageRef);
1385 writeStringToParcel(p, p_cur->ackPDU);
1386
1387 startResponse;
1388 appendPrintBuf("%s%d,%s", printBuf, p_cur->messageRef,
1389 (char*)p_cur->ackPDU);
1390 closeResponse;
1391
1392 return 0;
1393}
1394
Wink Savillef4c4d362009-04-02 01:37:03 -07001395static int responseDataCallList(Parcel &p, void *response, size_t responselen)
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001396{
1397 if (response == NULL && responselen != 0) {
1398 LOGE("invalid response: NULL");
1399 return RIL_ERRNO_INVALID_RESPONSE;
1400 }
1401
Wink Savillef4c4d362009-04-02 01:37:03 -07001402 if (responselen % sizeof(RIL_Data_Call_Response) != 0) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001403 LOGE("invalid response length %d expected multiple of %d",
Wink Savillef4c4d362009-04-02 01:37:03 -07001404 (int)responselen, (int)sizeof(RIL_Data_Call_Response));
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001405 return RIL_ERRNO_INVALID_RESPONSE;
1406 }
1407
Wink Savillef4c4d362009-04-02 01:37:03 -07001408 int num = responselen / sizeof(RIL_Data_Call_Response);
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001409 p.writeInt32(num);
1410
Wink Savillef4c4d362009-04-02 01:37:03 -07001411 RIL_Data_Call_Response *p_cur = (RIL_Data_Call_Response *) response;
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001412 startResponse;
1413 int i;
1414 for (i = 0; i < num; i++) {
1415 p.writeInt32(p_cur[i].cid);
1416 p.writeInt32(p_cur[i].active);
1417 writeStringToParcel(p, p_cur[i].type);
1418 writeStringToParcel(p, p_cur[i].apn);
1419 writeStringToParcel(p, p_cur[i].address);
1420 appendPrintBuf("%s[cid=%d,%s,%s,%s,%s],", printBuf,
1421 p_cur[i].cid,
1422 (p_cur[i].active==0)?"down":"up",
1423 (char*)p_cur[i].type,
1424 (char*)p_cur[i].apn,
1425 (char*)p_cur[i].address);
1426 }
1427 removeLastChar;
1428 closeResponse;
1429
1430 return 0;
1431}
1432
Wink Savillef4c4d362009-04-02 01:37:03 -07001433static int responseRaw(Parcel &p, void *response, size_t responselen) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001434 if (response == NULL && responselen != 0) {
1435 LOGE("invalid response: NULL with responselen != 0");
1436 return RIL_ERRNO_INVALID_RESPONSE;
1437 }
1438
1439 // The java code reads -1 size as null byte array
1440 if (response == NULL) {
1441 p.writeInt32(-1);
1442 } else {
1443 p.writeInt32(responselen);
1444 p.write(response, responselen);
1445 }
1446
1447 return 0;
1448}
1449
1450
Wink Savillef4c4d362009-04-02 01:37:03 -07001451static int responseSIM_IO(Parcel &p, void *response, size_t responselen) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001452 if (response == NULL) {
1453 LOGE("invalid response: NULL");
1454 return RIL_ERRNO_INVALID_RESPONSE;
1455 }
1456
1457 if (responselen != sizeof (RIL_SIM_IO_Response) ) {
1458 LOGE("invalid response length was %d expected %d",
1459 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
1460 return RIL_ERRNO_INVALID_RESPONSE;
1461 }
1462
1463 RIL_SIM_IO_Response *p_cur = (RIL_SIM_IO_Response *) response;
1464 p.writeInt32(p_cur->sw1);
1465 p.writeInt32(p_cur->sw2);
1466 writeStringToParcel(p, p_cur->simResponse);
1467
1468 startResponse;
1469 appendPrintBuf("%ssw1=0x%X,sw2=0x%X,%s", printBuf, p_cur->sw1, p_cur->sw2,
1470 (char*)p_cur->simResponse);
1471 closeResponse;
1472
1473
1474 return 0;
1475}
1476
Wink Savillef4c4d362009-04-02 01:37:03 -07001477static int responseCallForwards(Parcel &p, void *response, size_t responselen) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001478 int num;
1479
1480 if (response == NULL && responselen != 0) {
1481 LOGE("invalid response: NULL");
1482 return RIL_ERRNO_INVALID_RESPONSE;
1483 }
1484
1485 if (responselen % sizeof(RIL_CallForwardInfo *) != 0) {
1486 LOGE("invalid response length %d expected multiple of %d",
1487 (int)responselen, (int)sizeof(RIL_CallForwardInfo *));
1488 return RIL_ERRNO_INVALID_RESPONSE;
1489 }
1490
1491 /* number of call info's */
1492 num = responselen / sizeof(RIL_CallForwardInfo *);
1493 p.writeInt32(num);
1494
1495 startResponse;
1496 for (int i = 0 ; i < num ; i++) {
1497 RIL_CallForwardInfo *p_cur = ((RIL_CallForwardInfo **) response)[i];
1498
1499 p.writeInt32(p_cur->status);
1500 p.writeInt32(p_cur->reason);
1501 p.writeInt32(p_cur->serviceClass);
1502 p.writeInt32(p_cur->toa);
1503 writeStringToParcel(p, p_cur->number);
1504 p.writeInt32(p_cur->timeSeconds);
1505 appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
1506 (p_cur->status==1)?"enable":"disable",
1507 p_cur->reason, p_cur->serviceClass, p_cur->toa,
1508 (char*)p_cur->number,
1509 p_cur->timeSeconds);
1510 }
1511 removeLastChar;
1512 closeResponse;
1513
1514 return 0;
1515}
1516
Wink Savillef4c4d362009-04-02 01:37:03 -07001517static int responseSsn(Parcel &p, void *response, size_t responselen) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001518 if (response == NULL) {
1519 LOGE("invalid response: NULL");
1520 return RIL_ERRNO_INVALID_RESPONSE;
1521 }
1522
1523 if (responselen != sizeof(RIL_SuppSvcNotification)) {
1524 LOGE("invalid response length was %d expected %d",
1525 (int)responselen, (int)sizeof (RIL_SuppSvcNotification));
1526 return RIL_ERRNO_INVALID_RESPONSE;
1527 }
1528
1529 RIL_SuppSvcNotification *p_cur = (RIL_SuppSvcNotification *) response;
1530 p.writeInt32(p_cur->notificationType);
1531 p.writeInt32(p_cur->code);
1532 p.writeInt32(p_cur->index);
1533 p.writeInt32(p_cur->type);
1534 writeStringToParcel(p, p_cur->number);
1535
1536 startResponse;
1537 appendPrintBuf("%s%s,code=%d,id=%d,type=%d,%s", printBuf,
1538 (p_cur->notificationType==0)?"mo":"mt",
1539 p_cur->code, p_cur->index, p_cur->type,
1540 (char*)p_cur->number);
1541 closeResponse;
1542
1543 return 0;
1544}
1545
1546static int responseCellList(Parcel &p, void *response, size_t responselen)
1547{
1548 int num;
1549
1550 if (response == NULL && responselen != 0) {
1551 LOGE("invalid response: NULL");
1552 return RIL_ERRNO_INVALID_RESPONSE;
1553 }
1554
1555 if (responselen % sizeof (RIL_NeighboringCell *) != 0) {
1556 LOGE("invalid response length %d expected multiple of %d\n",
1557 (int)responselen, (int)sizeof (RIL_NeighboringCell *));
1558 return RIL_ERRNO_INVALID_RESPONSE;
1559 }
1560
1561 startResponse;
1562 /* number of cell info's */
1563 num = responselen / sizeof(RIL_NeighboringCell *);
1564 p.writeInt32(num);
1565
1566 for (int i = 0 ; i < num ; i++) {
1567 RIL_NeighboringCell *p_cur = ((RIL_NeighboringCell **) response)[i];
1568
1569 /* each cell info */
1570 p.writeInt32(p_cur->rssi);
1571 writeStringToParcel (p, p_cur->cid);
1572
1573 appendPrintBuf("%s[cid=%s,rssi=%d],", printBuf,
1574 p_cur->cid, p_cur->rssi);
1575 }
1576 removeLastChar;
1577 closeResponse;
1578
1579 return 0;
1580}
1581
1582static void triggerEvLoop()
1583{
1584 int ret;
1585 if (!pthread_equal(pthread_self(), s_tid_dispatch)) {
1586 /* trigger event loop to wakeup. No reason to do this,
1587 * if we're in the event loop thread */
1588 do {
1589 ret = write (s_fdWakeupWrite, " ", 1);
1590 } while (ret < 0 && errno == EINTR);
1591 }
1592}
1593
1594static void rilEventAddWakeup(struct ril_event *ev)
1595{
1596 ril_event_add(ev);
1597 triggerEvLoop();
1598}
1599
Wink Savillef4c4d362009-04-02 01:37:03 -07001600static int responseSimStatus(Parcel &p, void *response, size_t responselen) {
1601 int i;
1602
1603 if (response == NULL && responselen != 0) {
1604 LOGE("invalid response: NULL");
1605 return RIL_ERRNO_INVALID_RESPONSE;
1606 }
1607
1608 if (responselen % sizeof (RIL_CardStatus *) != 0) {
1609 LOGE("invalid response length %d expected multiple of %d\n",
1610 (int)responselen, (int)sizeof (RIL_CardStatus *));
1611 return RIL_ERRNO_INVALID_RESPONSE;
1612 }
1613
1614 RIL_CardStatus *p_cur = ((RIL_CardStatus *) response);
1615
1616 p.writeInt32(p_cur->card_state);
1617 p.writeInt32(p_cur->universal_pin_state);
1618 p.writeInt32(p_cur->gsm_umts_subscription_app_index);
1619 p.writeInt32(p_cur->cdma_subscription_app_index);
1620 p.writeInt32(p_cur->num_applications);
1621
1622 startResponse;
1623 for (i = 0; i < p_cur->num_applications; i++) {
1624 p.writeInt32(p_cur->applications[i].app_type);
1625 p.writeInt32(p_cur->applications[i].app_state);
1626 p.writeInt32(p_cur->applications[i].perso_substate);
1627 writeStringToParcel (p, (const char*)(p_cur->applications[i].aid_ptr));
1628 writeStringToParcel (p, (const char*)(p_cur->applications[i].app_label_ptr));
1629 p.writeInt32(p_cur->applications[i].pin1_replaced);
1630 p.writeInt32(p_cur->applications[i].pin1);
1631 p.writeInt32(p_cur->applications[i].pin2);
1632 appendPrintBuf("%s[app_type=%d,app_state=%d,perso_substate=%d,aid_ptr=%s,\
1633 app_label_ptr=%s,pin1_replaced=%d,pin1=%d,pin2=%d],",
1634 printBuf,
1635 p_cur->applications[i].app_type,
1636 p_cur->applications[i].app_state,
1637 p_cur->applications[i].perso_substate,
1638 p_cur->applications[i].aid_ptr,
1639 p_cur->applications[i].app_label_ptr,
1640 p_cur->applications[i].pin1_replaced,
1641 p_cur->applications[i].pin1,
1642 p_cur->applications[i].pin2);
1643 }
1644 closeResponse;
1645
1646 return 0;
1647}
1648
1649static int responseBrSmsCnf(Parcel &p, void *response, size_t responselen) {
1650 int num;
1651
1652 if (response == NULL && responselen != 0) {
1653 LOGE("invalid response: NULL");
1654 return RIL_ERRNO_INVALID_RESPONSE;
1655 }
1656
Wink Savillef5903df2009-04-24 11:54:14 -07001657 if (responselen % sizeof(RIL_BroadcastSMSConfig) != 0) {
Wink Savillef4c4d362009-04-02 01:37:03 -07001658 LOGE("invalid response length %d expected multiple of %d",
Wink Savillef5903df2009-04-24 11:54:14 -07001659 (int)responselen, (int)sizeof(RIL_BroadcastSMSConfig));
Wink Savillef4c4d362009-04-02 01:37:03 -07001660 return RIL_ERRNO_INVALID_RESPONSE;
1661 }
1662
1663 /* number of call info's */
1664 num = responselen / sizeof(RIL_BroadcastSMSConfig *);
1665 p.writeInt32(num);
1666
1667 RIL_BroadcastSMSConfig *p_cur = (RIL_BroadcastSMSConfig *) response;
1668 p.writeInt32(p_cur->size);
1669 p.writeInt32(p_cur->entries->uFromServiceID);
1670 p.writeInt32(p_cur->entries->uToserviceID);
1671 p.write(&(p_cur->entries->bSelected),sizeof(p_cur->entries->bSelected));
1672
1673 startResponse;
Wink Saville1b5fd232009-04-22 14:50:00 -07001674 appendPrintBuf("%s size=%d, entries.uFromServiceID=%d, \
Wink Savillef4c4d362009-04-02 01:37:03 -07001675 entries.uToserviceID=%d, entries.bSelected =%d, ",
1676 printBuf, p_cur->size,p_cur->entries->uFromServiceID,
Wink Saville1b5fd232009-04-22 14:50:00 -07001677 p_cur->entries->uToserviceID, p_cur->entries->bSelected);
Wink Savillef4c4d362009-04-02 01:37:03 -07001678 closeResponse;
1679
1680 return 0;
1681}
1682
1683static int responseCdmaBrCnf(Parcel &p, void *response, size_t responselen) {
Wink Savillef5903df2009-04-24 11:54:14 -07001684 int numServiceCategories;
Wink Savillef4c4d362009-04-02 01:37:03 -07001685
1686 if (response == NULL && responselen != 0) {
1687 LOGE("invalid response: NULL");
1688 return RIL_ERRNO_INVALID_RESPONSE;
1689 }
1690
Wink Savillef5903df2009-04-24 11:54:14 -07001691 if (responselen == 0) {
1692 LOGE("invalid response length %d expected >= of %d",
1693 (int)responselen, (int)sizeof(RIL_BroadcastSMSConfig));
Wink Savillef4c4d362009-04-02 01:37:03 -07001694 return RIL_ERRNO_INVALID_RESPONSE;
1695 }
1696
Wink Savillef5903df2009-04-24 11:54:14 -07001697 RIL_CDMA_BroadcastSMSConfig *p_cur = (RIL_CDMA_BroadcastSMSConfig *) response;
Wink Savillef4c4d362009-04-02 01:37:03 -07001698
Wink Savillef5903df2009-04-24 11:54:14 -07001699 numServiceCategories = p_cur->size;
Wink Savillef4c4d362009-04-02 01:37:03 -07001700 p.writeInt32(p_cur->size);
Wink Savillef4c4d362009-04-02 01:37:03 -07001701
1702 startResponse;
Wink Savillef5903df2009-04-24 11:54:14 -07001703 appendPrintBuf("%ssize=%d ", printBuf,p_cur->size);
Wink Savillef4c4d362009-04-02 01:37:03 -07001704 closeResponse;
1705
Wink Savillef5903df2009-04-24 11:54:14 -07001706 if (numServiceCategories != 0) {
1707 RIL_CDMA_BroadcastServiceInfo cdmaBsi[numServiceCategories];
1708 memcpy(cdmaBsi, p_cur->entries,
1709 sizeof(RIL_CDMA_BroadcastServiceInfo) * numServiceCategories);
1710
1711 for (int i = 0 ; i < numServiceCategories ; i++ ) {
1712 p.writeInt32(cdmaBsi[i].uServiceCategory);
1713 p.writeInt32(cdmaBsi[i].uLanguage);
1714 p.writeInt32(cdmaBsi[i].bSelected);
1715
1716 startResponse;
1717 appendPrintBuf("%sentries[%d].uServicecategory=%d, entries[%d].uLanguage =%d, \
1718 entries[%d].bSelected =%d, ", printBuf, i, cdmaBsi[i].uServiceCategory, i,
1719 cdmaBsi[i].uLanguage, i, cdmaBsi[i].bSelected);
1720 closeResponse;
1721 }
1722 } else {
1723 p.writeInt32(NULL);
1724 }
1725
Wink Savillef4c4d362009-04-02 01:37:03 -07001726 return 0;
1727}
1728
1729static int responseCdmaSms(Parcel &p, void *response, size_t responselen) {
1730 int num;
1731 int digitCount;
1732 int digitLimit;
1733 uint8_t uct;
1734 void* dest;
1735
Wink Savillef5903df2009-04-24 11:54:14 -07001736 LOGD("Inside responseCdmaSms");
1737
Wink Savillef4c4d362009-04-02 01:37:03 -07001738 if (response == NULL && responselen != 0) {
1739 LOGE("invalid response: NULL");
1740 return RIL_ERRNO_INVALID_RESPONSE;
1741 }
1742
Wink Savillef5903df2009-04-24 11:54:14 -07001743 if (responselen != sizeof(RIL_CDMA_SMS_Message)) {
Wink Savillef4c4d362009-04-02 01:37:03 -07001744 LOGE("invalid response length was %d expected %d",
Wink Savillef5903df2009-04-24 11:54:14 -07001745 (int)responselen, (int)sizeof(RIL_CDMA_SMS_Message));
Wink Savillef4c4d362009-04-02 01:37:03 -07001746 return RIL_ERRNO_INVALID_RESPONSE;
1747 }
1748
1749 RIL_CDMA_SMS_Message *p_cur = (RIL_CDMA_SMS_Message *) response;
1750 p.writeInt32(p_cur->uTeleserviceID);
1751 p.write(&(p_cur->bIsServicePresent),sizeof(uct));
1752 p.writeInt32(p_cur->uServicecategory);
1753 p.writeInt32(p_cur->sAddress.digit_mode);
1754 p.writeInt32(p_cur->sAddress.number_mode);
1755 p.writeInt32(p_cur->sAddress.number_type);
1756 p.writeInt32(p_cur->sAddress.number_plan);
1757 p.write(&(p_cur->sAddress.number_of_digits), sizeof(uct));
1758 digitLimit= MIN((p_cur->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
1759 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1760 p.write(&(p_cur->sAddress.digits[digitCount]),sizeof(uct));
1761 }
1762
1763 p.writeInt32(p_cur->sSubAddress.subaddressType);
1764 p.write(&(p_cur->sSubAddress.odd),sizeof(uct));
1765 p.write(&(p_cur->sSubAddress.number_of_digits),sizeof(uct));
1766 digitLimit= MIN((p_cur->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
1767 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1768 p.write(&(p_cur->sSubAddress.digits[digitCount]),sizeof(uct));
1769 }
1770
1771 digitLimit= MIN((p_cur->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
1772 p.writeInt32(p_cur->uBearerDataLen);
1773 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1774 p.write(&(p_cur->aBearerData[digitCount]), sizeof(uct));
1775 }
1776
1777 startResponse;
1778 appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
Wink Saville1b5fd232009-04-22 14:50:00 -07001779 sAddress.digit_mode=%d, sAddress.number_mode=%d, sAddress.number_type=%d, ",
Wink Savillef4c4d362009-04-02 01:37:03 -07001780 printBuf, p_cur->uTeleserviceID,p_cur->bIsServicePresent,p_cur->uServicecategory,
1781 p_cur->sAddress.digit_mode, p_cur->sAddress.number_mode,p_cur->sAddress.number_type);
1782 closeResponse;
1783
1784 return 0;
1785}
1786
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001787/**
1788 * A write on the wakeup fd is done just to pop us out of select()
1789 * We empty the buffer here and then ril_event will reset the timers on the
1790 * way back down
1791 */
Wink Savillef4c4d362009-04-02 01:37:03 -07001792static void processWakeupCallback(int fd, short flags, void *param) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001793 char buff[16];
1794 int ret;
1795
1796 LOGV("processWakeupCallback");
1797
1798 /* empty our wakeup socket out */
1799 do {
1800 ret = read(s_fdWakeupRead, &buff, sizeof(buff));
1801 } while (ret > 0 || (ret < 0 && errno == EINTR));
1802}
1803
Wink Savillef4c4d362009-04-02 01:37:03 -07001804static void onCommandsSocketClosed() {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001805 int ret;
1806 RequestInfo *p_cur;
1807
1808 /* mark pending requests as "cancelled" so we dont report responses */
1809
1810 ret = pthread_mutex_lock(&s_pendingRequestsMutex);
1811 assert (ret == 0);
1812
1813 p_cur = s_pendingRequests;
1814
1815 for (p_cur = s_pendingRequests
1816 ; p_cur != NULL
1817 ; p_cur = p_cur->p_next
1818 ) {
1819 p_cur->cancelled = 1;
1820 }
1821
1822 ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
1823 assert (ret == 0);
1824}
1825
Wink Savillef4c4d362009-04-02 01:37:03 -07001826static void processCommandsCallback(int fd, short flags, void *param) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001827 RecordStream *p_rs;
1828 void *p_record;
1829 size_t recordlen;
1830 int ret;
1831
1832 assert(fd == s_fdCommand);
1833
1834 p_rs = (RecordStream *)param;
1835
1836 for (;;) {
1837 /* loop until EAGAIN/EINTR, end of stream, or other error */
1838 ret = record_stream_get_next(p_rs, &p_record, &recordlen);
1839
1840 if (ret == 0 && p_record == NULL) {
1841 /* end-of-stream */
1842 break;
1843 } else if (ret < 0) {
1844 break;
1845 } else if (ret == 0) { /* && p_record != NULL */
1846 processCommandBuffer(p_record, recordlen);
1847 }
1848 }
1849
1850 if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) {
1851 /* fatal error or end-of-stream */
1852 if (ret != 0) {
1853 LOGE("error on reading command socket errno:%d\n", errno);
1854 } else {
1855 LOGW("EOS. Closing command socket.");
1856 }
1857
1858 close(s_fdCommand);
1859 s_fdCommand = -1;
1860
1861 ril_event_del(&s_commands_event);
1862
1863 record_stream_free(p_rs);
1864
1865 /* start listening for new connections again */
1866 rilEventAddWakeup(&s_listen_event);
1867
1868 onCommandsSocketClosed();
1869 }
1870}
1871
1872
Wink Savillef4c4d362009-04-02 01:37:03 -07001873static void onNewCommandConnect() {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001874 // implicit radio state changed
1875 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
1876 NULL, 0);
1877
1878 // Send last NITZ time data, in case it was missed
1879 if (s_lastNITZTimeData != NULL) {
1880 sendResponseRaw(s_lastNITZTimeData, s_lastNITZTimeDataSize);
1881
1882 free(s_lastNITZTimeData);
1883 s_lastNITZTimeData = NULL;
1884 }
1885
1886 // Get version string
1887 if (s_callbacks.getVersion != NULL) {
1888 const char *version;
1889 version = s_callbacks.getVersion();
1890 LOGI("RIL Daemon version: %s\n", version);
1891
1892 property_set(PROPERTY_RIL_IMPL, version);
1893 } else {
1894 LOGI("RIL Daemon version: unavailable\n");
1895 property_set(PROPERTY_RIL_IMPL, "unavailable");
1896 }
1897
1898}
1899
Wink Savillef4c4d362009-04-02 01:37:03 -07001900static void listenCallback (int fd, short flags, void *param) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001901 int ret;
1902 int err;
1903 int is_phone_socket;
1904 RecordStream *p_rs;
1905
1906 struct sockaddr_un peeraddr;
1907 socklen_t socklen = sizeof (peeraddr);
1908
1909 struct ucred creds;
1910 socklen_t szCreds = sizeof(creds);
1911
1912 struct passwd *pwd = NULL;
1913
1914 assert (s_fdCommand < 0);
1915 assert (fd == s_fdListen);
1916
1917 s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);
1918
1919 if (s_fdCommand < 0 ) {
1920 LOGE("Error on accept() errno:%d", errno);
1921 /* start listening for new connections again */
1922 rilEventAddWakeup(&s_listen_event);
Wink Savillef4c4d362009-04-02 01:37:03 -07001923 return;
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001924 }
1925
1926 /* check the credential of the other side and only accept socket from
1927 * phone process
1928 */
1929 errno = 0;
1930 is_phone_socket = 0;
Wink Savillef4c4d362009-04-02 01:37:03 -07001931
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001932 err = getsockopt(s_fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds);
Wink Savillef4c4d362009-04-02 01:37:03 -07001933
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001934 if (err == 0 && szCreds > 0) {
Wink Savillef4c4d362009-04-02 01:37:03 -07001935 errno = 0;
1936 pwd = getpwuid(creds.uid);
1937 if (pwd != NULL) {
1938 if (strcmp(pwd->pw_name, PHONE_PROCESS) == 0) {
1939 is_phone_socket = 1;
1940 } else {
1941 LOGE("RILD can't accept socket from process %s", pwd->pw_name);
1942 }
1943 } else {
1944 LOGE("Error on getpwuid() errno: %d", errno);
1945 }
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001946 } else {
Wink Savillef4c4d362009-04-02 01:37:03 -07001947 LOGD("Error on getsockopt() errno: %d", errno);
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001948 }
1949
1950 if ( !is_phone_socket ) {
1951 LOGE("RILD must accept socket from %s", PHONE_PROCESS);
1952
1953 close(s_fdCommand);
1954 s_fdCommand = -1;
1955
1956 onCommandsSocketClosed();
1957
1958 /* start listening for new connections again */
1959 rilEventAddWakeup(&s_listen_event);
1960
1961 return;
1962 }
1963
1964 ret = fcntl(s_fdCommand, F_SETFL, O_NONBLOCK);
1965
1966 if (ret < 0) {
1967 LOGE ("Error setting O_NONBLOCK errno:%d", errno);
1968 }
1969
1970 LOGI("libril: new connection");
1971
1972 p_rs = record_stream_new(s_fdCommand, MAX_COMMAND_BYTES);
1973
1974 ril_event_set (&s_commands_event, s_fdCommand, 1,
1975 processCommandsCallback, p_rs);
1976
1977 rilEventAddWakeup (&s_commands_event);
1978
1979 onNewCommandConnect();
1980}
1981
1982static void freeDebugCallbackArgs(int number, char **args) {
1983 for (int i = 0; i < number; i++) {
1984 if (args[i] != NULL) {
1985 free(args[i]);
1986 }
1987 }
1988 free(args);
1989}
1990
Wink Savillef4c4d362009-04-02 01:37:03 -07001991static void debugCallback (int fd, short flags, void *param) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08001992 int acceptFD, option;
1993 struct sockaddr_un peeraddr;
1994 socklen_t socklen = sizeof (peeraddr);
1995 int data;
1996 unsigned int qxdm_data[6];
1997 const char *deactData[1] = {"1"};
1998 char *actData[1];
1999 RIL_Dial dialData;
2000 int hangupData[1] = {1};
2001 int number;
2002 char **args;
2003
2004 acceptFD = accept (fd, (sockaddr *) &peeraddr, &socklen);
2005
2006 if (acceptFD < 0) {
2007 LOGE ("error accepting on debug port: %d\n", errno);
2008 return;
2009 }
2010
2011 if (recv(acceptFD, &number, sizeof(int), 0) != sizeof(int)) {
2012 LOGE ("error reading on socket: number of Args: \n");
2013 return;
2014 }
2015 args = (char **) malloc(sizeof(char*) * number);
2016
2017 for (int i = 0; i < number; i++) {
2018 int len;
2019 if (recv(acceptFD, &len, sizeof(int), 0) != sizeof(int)) {
2020 LOGE ("error reading on socket: Len of Args: \n");
2021 freeDebugCallbackArgs(i, args);
2022 return;
2023 }
2024 // +1 for null-term
2025 args[i] = (char *) malloc((sizeof(char) * len) + 1);
2026 if (recv(acceptFD, args[i], sizeof(char) * len, 0)
Wink Saville1b5fd232009-04-22 14:50:00 -07002027 != (int)sizeof(char) * len) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002028 LOGE ("error reading on socket: Args[%d] \n", i);
2029 freeDebugCallbackArgs(i, args);
2030 return;
2031 }
2032 char * buf = args[i];
2033 buf[len] = 0;
2034 }
2035
2036 switch (atoi(args[0])) {
2037 case 0:
2038 LOGI ("Connection on debug port: issuing reset.");
2039 issueLocalRequest(RIL_REQUEST_RESET_RADIO, NULL, 0);
2040 break;
2041 case 1:
2042 LOGI ("Connection on debug port: issuing radio power off.");
2043 data = 0;
2044 issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int));
2045 // Close the socket
2046 close(s_fdCommand);
2047 s_fdCommand = -1;
2048 break;
2049 case 2:
2050 LOGI ("Debug port: issuing unsolicited network change.");
2051 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED,
2052 NULL, 0);
2053 break;
2054 case 3:
2055 LOGI ("Debug port: QXDM log enable.");
2056 qxdm_data[0] = 65536;
2057 qxdm_data[1] = 16;
2058 qxdm_data[2] = 1;
2059 qxdm_data[3] = 32;
2060 qxdm_data[4] = 0;
2061 qxdm_data[4] = 8;
2062 issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
2063 6 * sizeof(int));
2064 break;
2065 case 4:
2066 LOGI ("Debug port: QXDM log disable.");
2067 qxdm_data[0] = 65536;
2068 qxdm_data[1] = 16;
2069 qxdm_data[2] = 0;
2070 qxdm_data[3] = 32;
2071 qxdm_data[4] = 0;
2072 qxdm_data[4] = 8;
2073 issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
2074 6 * sizeof(int));
2075 break;
2076 case 5:
2077 LOGI("Debug port: Radio On");
2078 data = 1;
2079 issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int));
2080 sleep(2);
2081 // Set network selection automatic.
2082 issueLocalRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, NULL, 0);
2083 break;
2084 case 6:
Wink Savillef4c4d362009-04-02 01:37:03 -07002085 LOGI("Debug port: Setup Data Call, Apn :%s\n", args[1]);
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002086 actData[0] = args[1];
Wink Savillef4c4d362009-04-02 01:37:03 -07002087 issueLocalRequest(RIL_REQUEST_SETUP_DATA_CALL, &actData,
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002088 sizeof(actData));
2089 break;
2090 case 7:
Wink Savillef4c4d362009-04-02 01:37:03 -07002091 LOGI("Debug port: Deactivate Data Call");
2092 issueLocalRequest(RIL_REQUEST_DEACTIVATE_DATA_CALL, &deactData,
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002093 sizeof(deactData));
2094 break;
2095 case 8:
2096 LOGI("Debug port: Dial Call");
2097 dialData.clir = 0;
2098 dialData.address = args[1];
2099 issueLocalRequest(RIL_REQUEST_DIAL, &dialData, sizeof(dialData));
2100 break;
2101 case 9:
2102 LOGI("Debug port: Answer Call");
2103 issueLocalRequest(RIL_REQUEST_ANSWER, NULL, 0);
2104 break;
2105 case 10:
2106 LOGI("Debug port: End Call");
2107 issueLocalRequest(RIL_REQUEST_HANGUP, &hangupData,
2108 sizeof(hangupData));
2109 break;
2110 default:
2111 LOGE ("Invalid request");
2112 break;
2113 }
2114 freeDebugCallbackArgs(number, args);
2115 close(acceptFD);
2116}
2117
2118
Wink Savillef4c4d362009-04-02 01:37:03 -07002119static void userTimerCallback (int fd, short flags, void *param) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002120 UserCallbackInfo *p_info;
2121
2122 p_info = (UserCallbackInfo *)param;
2123
2124 p_info->p_callback(p_info->userParam);
2125
2126
2127 // FIXME generalize this...there should be a cancel mechanism
2128 if (s_last_wake_timeout_info != NULL && s_last_wake_timeout_info == p_info) {
2129 s_last_wake_timeout_info = NULL;
2130 }
2131
2132 free(p_info);
2133}
2134
2135
2136static void *
Wink Savillef4c4d362009-04-02 01:37:03 -07002137eventLoop(void *param) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002138 int ret;
2139 int filedes[2];
2140
2141 ril_event_init();
2142
2143 pthread_mutex_lock(&s_startupMutex);
2144
2145 s_started = 1;
2146 pthread_cond_broadcast(&s_startupCond);
2147
2148 pthread_mutex_unlock(&s_startupMutex);
2149
2150 ret = pipe(filedes);
2151
2152 if (ret < 0) {
2153 LOGE("Error in pipe() errno:%d", errno);
2154 return NULL;
2155 }
2156
2157 s_fdWakeupRead = filedes[0];
2158 s_fdWakeupWrite = filedes[1];
2159
2160 fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
2161
2162 ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
2163 processWakeupCallback, NULL);
2164
2165 rilEventAddWakeup (&s_wakeupfd_event);
2166
2167 // Only returns on error
2168 ril_event_loop();
2169 LOGE ("error in event_loop_base errno:%d", errno);
2170
2171 return NULL;
2172}
2173
2174extern "C" void
Wink Savillef4c4d362009-04-02 01:37:03 -07002175RIL_startEventLoop(void) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002176 int ret;
2177 pthread_attr_t attr;
2178
2179 /* spin up eventLoop thread and wait for it to get started */
2180 s_started = 0;
2181 pthread_mutex_lock(&s_startupMutex);
2182
2183 pthread_attr_init (&attr);
2184 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2185 ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
2186
2187 while (s_started == 0) {
2188 pthread_cond_wait(&s_startupCond, &s_startupMutex);
2189 }
2190
2191 pthread_mutex_unlock(&s_startupMutex);
2192
2193 if (ret < 0) {
2194 LOGE("Failed to create dispatch thread errno:%d", errno);
2195 return;
2196 }
2197}
2198
2199// Used for testing purpose only.
2200extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) {
2201 memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
2202}
2203
2204extern "C" void
Wink Savillef4c4d362009-04-02 01:37:03 -07002205RIL_register (const RIL_RadioFunctions *callbacks) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002206 int ret;
2207 int flags;
2208
2209 if (callbacks == NULL
2210 || ! (callbacks->version == RIL_VERSION || callbacks->version == 1)
2211 ) {
2212 LOGE(
2213 "RIL_register: RIL_RadioFunctions * null or invalid version"
2214 " (expected %d)", RIL_VERSION);
2215 return;
2216 }
2217
2218 if (s_registerCalled > 0) {
2219 LOGE("RIL_register has been called more than once. "
2220 "Subsequent call ignored");
2221 return;
2222 }
2223
2224 memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
2225
2226 s_registerCalled = 1;
2227
2228 // Little self-check
2229
Wink Savillef4c4d362009-04-02 01:37:03 -07002230 for (int i = 0; i < (int)NUM_ELEMS(s_commands); i++) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002231 assert(i == s_commands[i].requestNumber);
2232 }
2233
Wink Savillef4c4d362009-04-02 01:37:03 -07002234 for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses); i++) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002235 assert(i + RIL_UNSOL_RESPONSE_BASE
2236 == s_unsolResponses[i].requestNumber);
2237 }
2238
2239 // New rild impl calls RIL_startEventLoop() first
2240 // old standalone impl wants it here.
2241
2242 if (s_started == 0) {
2243 RIL_startEventLoop();
2244 }
2245
2246 // start listen socket
2247
2248#if 0
2249 ret = socket_local_server (SOCKET_NAME_RIL,
2250 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
2251
2252 if (ret < 0) {
2253 LOGE("Unable to bind socket errno:%d", errno);
2254 exit (-1);
2255 }
2256 s_fdListen = ret;
2257
2258#else
2259 s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);
2260 if (s_fdListen < 0) {
2261 LOGE("Failed to get socket '" SOCKET_NAME_RIL "'");
2262 exit(-1);
2263 }
2264
2265 ret = listen(s_fdListen, 4);
2266
2267 if (ret < 0) {
2268 LOGE("Failed to listen on control socket '%d': %s",
2269 s_fdListen, strerror(errno));
2270 exit(-1);
2271 }
2272#endif
2273
2274
2275 /* note: non-persistent so we can accept only one connection at a time */
2276 ril_event_set (&s_listen_event, s_fdListen, false,
2277 listenCallback, NULL);
2278
2279 rilEventAddWakeup (&s_listen_event);
2280
2281#if 1
2282 // start debug interface socket
2283
2284 s_fdDebug = android_get_control_socket(SOCKET_NAME_RIL_DEBUG);
2285 if (s_fdDebug < 0) {
2286 LOGE("Failed to get socket '" SOCKET_NAME_RIL_DEBUG "' errno:%d", errno);
2287 exit(-1);
2288 }
2289
2290 ret = listen(s_fdDebug, 4);
2291
2292 if (ret < 0) {
2293 LOGE("Failed to listen on ril debug socket '%d': %s",
2294 s_fdDebug, strerror(errno));
2295 exit(-1);
2296 }
2297
2298 ril_event_set (&s_debug_event, s_fdDebug, true,
2299 debugCallback, NULL);
2300
2301 rilEventAddWakeup (&s_debug_event);
2302#endif
2303
2304}
2305
2306static int
Wink Savillef4c4d362009-04-02 01:37:03 -07002307checkAndDequeueRequestInfo(struct RequestInfo *pRI) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002308 int ret = 0;
2309
2310 if (pRI == NULL) {
2311 return 0;
2312 }
2313
2314 pthread_mutex_lock(&s_pendingRequestsMutex);
2315
2316 for(RequestInfo **ppCur = &s_pendingRequests
2317 ; *ppCur != NULL
2318 ; ppCur = &((*ppCur)->p_next)
2319 ) {
2320 if (pRI == *ppCur) {
2321 ret = 1;
2322
2323 *ppCur = (*ppCur)->p_next;
2324 break;
2325 }
2326 }
2327
2328 pthread_mutex_unlock(&s_pendingRequestsMutex);
2329
2330 return ret;
2331}
2332
2333
2334extern "C" void
Wink Savillef4c4d362009-04-02 01:37:03 -07002335RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002336 RequestInfo *pRI;
2337 int ret;
2338 size_t errorOffset;
2339
2340 pRI = (RequestInfo *)t;
2341
2342 if (!checkAndDequeueRequestInfo(pRI)) {
2343 LOGE ("RIL_onRequestComplete: invalid RIL_Token");
2344 return;
2345 }
2346
2347 if (pRI->local > 0) {
2348 // Locally issued command...void only!
2349 // response does not go back up the command socket
2350 LOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
2351
2352 goto done;
2353 }
2354
2355 appendPrintBuf("[%04d]< %s",
2356 pRI->token, requestToString(pRI->pCI->requestNumber));
2357
2358 if (pRI->cancelled == 0) {
2359 Parcel p;
2360
2361 p.writeInt32 (RESPONSE_SOLICITED);
2362 p.writeInt32 (pRI->token);
2363 errorOffset = p.dataPosition();
2364
2365 p.writeInt32 (e);
2366
2367 if (e == RIL_E_SUCCESS) {
2368 /* process response on success */
2369 ret = pRI->pCI->responseFunction(p, response, responselen);
2370
2371 /* if an error occurred, rewind and mark it */
2372 if (ret != 0) {
2373 p.setDataPosition(errorOffset);
2374 p.writeInt32 (ret);
2375 }
2376 } else {
2377 appendPrintBuf("%s returns %s", printBuf, failCauseToString(e));
2378 }
2379
2380 if (s_fdCommand < 0) {
2381 LOGD ("RIL onRequestComplete: Command channel closed");
2382 }
2383 sendResponse(p);
2384 }
2385
2386done:
2387 free(pRI);
2388}
2389
2390
2391static void
Wink Savillef4c4d362009-04-02 01:37:03 -07002392grabPartialWakeLock() {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002393 acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
2394}
2395
2396static void
Wink Savillef4c4d362009-04-02 01:37:03 -07002397releaseWakeLock() {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002398 release_wake_lock(ANDROID_WAKE_LOCK_NAME);
2399}
2400
2401/**
2402 * Timer callback to put us back to sleep before the default timeout
2403 */
2404static void
Wink Savillef4c4d362009-04-02 01:37:03 -07002405wakeTimeoutCallback (void *param) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002406 // We're using "param != NULL" as a cancellation mechanism
2407 if (param == NULL) {
2408 //LOGD("wakeTimeout: releasing wake lock");
2409
2410 releaseWakeLock();
2411 } else {
2412 //LOGD("wakeTimeout: releasing wake lock CANCELLED");
2413 }
2414}
2415
2416extern "C"
2417void RIL_onUnsolicitedResponse(int unsolResponse, void *data,
2418 size_t datalen)
2419{
2420 int unsolResponseIndex;
2421 int ret;
2422 int64_t timeReceived = 0;
2423 bool shouldScheduleTimeout = false;
2424
2425 if (s_registerCalled == 0) {
2426 // Ignore RIL_onUnsolicitedResponse before RIL_register
2427 LOGW("RIL_onUnsolicitedResponse called before RIL_register");
2428 return;
2429 }
The Android Open Source Project34a51082009-03-05 14:34:37 -08002430
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002431 unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
2432
2433 if ((unsolResponseIndex < 0)
2434 || (unsolResponseIndex >= (int32_t)NUM_ELEMS(s_unsolResponses))) {
2435 LOGE("unsupported unsolicited response code %d", unsolResponse);
2436 return;
2437 }
2438
2439 // Grab a wake lock if needed for this reponse,
2440 // as we exit we'll either release it immediately
2441 // or set a timer to release it later.
2442 switch (s_unsolResponses[unsolResponseIndex].wakeType) {
2443 case WAKE_PARTIAL:
2444 grabPartialWakeLock();
2445 shouldScheduleTimeout = true;
2446 break;
2447
2448 case DONT_WAKE:
2449 default:
2450 // No wake lock is grabed so don't set timeout
2451 shouldScheduleTimeout = false;
2452 break;
2453 }
2454
2455 // Mark the time this was received, doing this
2456 // after grabing the wakelock incase getting
2457 // the elapsedRealTime might cause us to goto
2458 // sleep.
2459 if (unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
2460 timeReceived = elapsedRealtime();
2461 }
2462
2463 appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
2464
2465 Parcel p;
2466
2467 p.writeInt32 (RESPONSE_UNSOLICITED);
2468 p.writeInt32 (unsolResponse);
2469
2470 ret = s_unsolResponses[unsolResponseIndex]
2471 .responseFunction(p, data, datalen);
2472 if (ret != 0) {
2473 // Problem with the response. Don't continue;
2474 goto error_exit;
2475 }
2476
2477 // some things get more payload
2478 switch(unsolResponse) {
2479 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
2480 p.writeInt32(s_callbacks.onStateRequest());
2481 appendPrintBuf("%s {%s}", printBuf,
2482 radioStateToString(s_callbacks.onStateRequest()));
2483 break;
2484
2485
2486 case RIL_UNSOL_NITZ_TIME_RECEIVED:
2487 // Store the time that this was received so the
2488 // handler of this message can account for
2489 // the time it takes to arrive and process. In
2490 // particular the system has been known to sleep
2491 // before this message can be processed.
2492 p.writeInt64(timeReceived);
2493 break;
2494 }
2495
2496 ret = sendResponse(p);
2497 if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
2498
2499 // Unfortunately, NITZ time is not poll/update like everything
2500 // else in the system. So, if the upstream client isn't connected,
2501 // keep a copy of the last NITZ response (with receive time noted
2502 // above) around so we can deliver it when it is connected
2503
2504 if (s_lastNITZTimeData != NULL) {
2505 free (s_lastNITZTimeData);
2506 s_lastNITZTimeData = NULL;
2507 }
2508
2509 s_lastNITZTimeData = malloc(p.dataSize());
2510 s_lastNITZTimeDataSize = p.dataSize();
2511 memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
2512 }
2513
2514 // For now, we automatically go back to sleep after TIMEVAL_WAKE_TIMEOUT
2515 // FIXME The java code should handshake here to release wake lock
2516
2517 if (shouldScheduleTimeout) {
2518 // Cancel the previous request
2519 if (s_last_wake_timeout_info != NULL) {
2520 s_last_wake_timeout_info->userParam = (void *)1;
2521 }
2522
2523 s_last_wake_timeout_info
2524 = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
2525 &TIMEVAL_WAKE_TIMEOUT);
2526 }
2527
2528 // Normal exit
2529 return;
2530
2531error_exit:
2532 // There was an error and we've got the wake lock so release it.
2533 if (shouldScheduleTimeout) {
2534 releaseWakeLock();
2535 }
2536}
2537
2538/** FIXME generalize this if you track UserCAllbackInfo, clear it
2539 when the callback occurs
2540*/
2541static UserCallbackInfo *
2542internalRequestTimedCallback (RIL_TimedCallback callback, void *param,
2543 const struct timeval *relativeTime)
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002544{
2545 struct timeval myRelativeTime;
2546 UserCallbackInfo *p_info;
2547
2548 p_info = (UserCallbackInfo *) malloc (sizeof(UserCallbackInfo));
2549
2550 p_info->p_callback = callback;
2551 p_info->userParam = param;
2552
2553 if (relativeTime == NULL) {
2554 /* treat null parameter as a 0 relative time */
2555 memset (&myRelativeTime, 0, sizeof(myRelativeTime));
2556 } else {
2557 /* FIXME I think event_add's tv param is really const anyway */
2558 memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime));
2559 }
2560
2561 ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info);
2562
2563 ril_timer_add(&(p_info->event), &myRelativeTime);
2564
2565 triggerEvLoop();
2566 return p_info;
2567}
2568
2569
2570extern "C" void
2571RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
Wink Savillef4c4d362009-04-02 01:37:03 -07002572 const struct timeval *relativeTime) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002573 internalRequestTimedCallback (callback, param, relativeTime);
2574}
2575
2576const char *
Wink Savillef4c4d362009-04-02 01:37:03 -07002577failCauseToString(RIL_Errno e) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002578 switch(e) {
2579 case RIL_E_SUCCESS: return "E_SUCCESS";
2580 case RIL_E_RADIO_NOT_AVAILABLE: return "E_RAIDO_NOT_AVAILABLE";
2581 case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE";
2582 case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT";
2583 case RIL_E_SIM_PIN2: return "E_SIM_PIN2";
2584 case RIL_E_SIM_PUK2: return "E_SIM_PUK2";
2585 case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED";
2586 case RIL_E_CANCELLED: return "E_CANCELLED";
2587 case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL";
2588 case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW";
2589 case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY";
Wink Savillef4c4d362009-04-02 01:37:03 -07002590 case RIL_E_SIM_ABSENT:return "E_SIM_ABSENT";
2591#ifdef FEATURE_MULTIMODE_ANDROID
2592 case RIL_E_SUBSCRIPTION_NOT_AVAILABLE:return "E_SUBSCRIPTION_NOT_AVAILABLE";
2593 case RIL_E_MODE_NOT_SUPPORTED:return "E_MODE_NOT_SUPPORTED";
2594#endif
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002595 default: return "<unknown error>";
2596 }
2597}
2598
2599const char *
Wink Savillef4c4d362009-04-02 01:37:03 -07002600radioStateToString(RIL_RadioState s) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002601 switch(s) {
2602 case RADIO_STATE_OFF: return "RADIO_OFF";
2603 case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE";
2604 case RADIO_STATE_SIM_NOT_READY: return "RADIO_SIM_NOT_READY";
2605 case RADIO_STATE_SIM_LOCKED_OR_ABSENT: return "RADIO_SIM_LOCKED_OR_ABSENT";
2606 case RADIO_STATE_SIM_READY: return "RADIO_SIM_READY";
Wink Savillef4c4d362009-04-02 01:37:03 -07002607 case RADIO_STATE_RUIM_NOT_READY:return"RADIO_RUIM_NOT_READY";
2608 case RADIO_STATE_RUIM_READY:return"RADIO_RUIM_READY";
2609 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:return"RADIO_RUIM_LOCKED_OR_ABSENT";
2610 case RADIO_STATE_NV_NOT_READY:return"RADIO_NV_NOT_READY";
2611 case RADIO_STATE_NV_READY:return"RADIO_NV_READY";
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002612 default: return "<unknown state>";
2613 }
2614}
2615
2616const char *
Wink Savillef4c4d362009-04-02 01:37:03 -07002617callStateToString(RIL_CallState s) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002618 switch(s) {
2619 case RIL_CALL_ACTIVE : return "ACTIVE";
2620 case RIL_CALL_HOLDING: return "HOLDING";
2621 case RIL_CALL_DIALING: return "DIALING";
2622 case RIL_CALL_ALERTING: return "ALERTING";
2623 case RIL_CALL_INCOMING: return "INCOMING";
2624 case RIL_CALL_WAITING: return "WAITING";
2625 default: return "<unknown state>";
2626 }
2627}
2628
2629const char *
Wink Savillef4c4d362009-04-02 01:37:03 -07002630requestToString(int request) {
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002631/*
2632 cat libs/telephony/ril_commands.h \
2633 | egrep "^ *{RIL_" \
2634 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
2635
2636
2637 cat libs/telephony/ril_unsol_commands.h \
2638 | egrep "^ *{RIL_" \
2639 | sed -re 's/\{RIL_([^,]+),([^}]+).+/case RIL_\1: return "\1";/'
2640
2641*/
2642 switch(request) {
2643 case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
2644 case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
2645 case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
2646 case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
2647 case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
2648 case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
2649 case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
2650 case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
2651 case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
2652 case RIL_REQUEST_DIAL: return "DIAL";
2653 case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
2654 case RIL_REQUEST_HANGUP: return "HANGUP";
2655 case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
2656 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
2657 case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
2658 case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
2659 case RIL_REQUEST_UDUB: return "UDUB";
2660 case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
2661 case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
2662 case RIL_REQUEST_REGISTRATION_STATE: return "REGISTRATION_STATE";
2663 case RIL_REQUEST_GPRS_REGISTRATION_STATE: return "GPRS_REGISTRATION_STATE";
2664 case RIL_REQUEST_OPERATOR: return "OPERATOR";
2665 case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
2666 case RIL_REQUEST_DTMF: return "DTMF";
2667 case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
2668 case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
Wink Savillef4c4d362009-04-02 01:37:03 -07002669 case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002670 case RIL_REQUEST_SIM_IO: return "SIM_IO";
2671 case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
2672 case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
2673 case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
2674 case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
2675 case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
2676 case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
2677 case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
2678 case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
2679 case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
2680 case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
2681 case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
2682 case RIL_REQUEST_ANSWER: return "ANSWER";
Wink Savillef4c4d362009-04-02 01:37:03 -07002683 case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002684 case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
2685 case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
2686 case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
2687 case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
2688 case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
2689 case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
2690 case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
2691 case RIL_REQUEST_DTMF_START: return "DTMF_START";
2692 case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
2693 case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
2694 case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
2695 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE";
2696 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE";
2697 case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS";
2698 case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
2699 case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
2700 case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
Wink Savillef4c4d362009-04-02 01:37:03 -07002701 case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
2702 case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002703 case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
2704 case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
2705 case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
Wink Savillef4c4d362009-04-02 01:37:03 -07002706 case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
2707 case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002708 case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE";
2709 case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE";
2710 case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND";
2711 case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE";
2712 case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
2713 case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
2714 case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER";
2715 case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES";
Wink Savillef4c4d362009-04-02 01:37:03 -07002716 case RIL_REQUEST_CDMA_SET_SUBSCRIPTION:return"CDMA_SET_SUBSCRIPTION";
2717 case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:return"CDMA_SET_ROAMING_PREFERENCE";
2718 case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:return"CDMA_QUERY_ROAMING_PREFERENCE";
2719 case RIL_REQUEST_SET_TTY_MODE:return"SET_TTY_MODE";
2720 case RIL_REQUEST_QUERY_TTY_MODE:return"QUERY_TTY_MODE";
2721 case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
2722 case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
2723 case RIL_REQUEST_CDMA_FLASH:return"CDMA_FLASH";
2724 case RIL_REQUEST_CDMA_BURST_DTMF:return"CDMA_BURST_DTMF";
2725 case RIL_REQUEST_CDMA_SEND_SMS:return"CDMA_SEND_SMS";
2726 case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:return"CDMA_SMS_ACKNOWLEDGE";
2727 case RIL_REQUEST_GET_BROADCAST_CONFIG:return"GET_BROADCAST_CONFIG";
2728 case RIL_REQUEST_SET_BROADCAST_CONFIG:return"SET_BROADCAST_CONFIG";
2729 case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG:return "CDMA_GET_BROADCAST_CONFIG";
2730 case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG:return "SET_CDMA_BROADCAST_CONFIG";
2731 case RIL_REQUEST_BROADCAST_ACTIVATION:return "BROADCAST_ACTIVATION";
2732 case RIL_REQUEST_CDMA_VALIDATE_AKEY: return"CDMA_VALIDATE_AKEY";
2733 case RIL_REQUEST_CDMA_SUBSCRIPTION: return"CDMA_SUBSCRIPTION";
2734 case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "CDMA_WRITE_SMS_TO_RUIM";
2735 case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "CDMA_DELETE_SMS_ON_RUIM";
2736 case RIL_REQUEST_DEVICE_IDENTITY: return "DEVICE_IDENTITY";
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002737 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
2738 case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
2739 case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_NETWORK_STATE_CHANGED";
2740 case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
2741 case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
2742 case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
2743 case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
2744 case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
2745 case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
2746 case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
2747 case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
2748 case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
2749 case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
2750 case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
2751 case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FUL";
2752 case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
Wink Savillef4c4d362009-04-02 01:37:03 -07002753 case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002754 case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
The Android Open Source Project34a51082009-03-05 14:34:37 -08002755 case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
Wink Savillef4c4d362009-04-02 01:37:03 -07002756 case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
2757 case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_NEW_CDMA_SMS";
2758 case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_NEW_BROADCAST_SMS";
2759 case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
Jaikumar Ganeshaf6ecbf2009-04-29 13:27:51 -07002760 case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
The Android Open Source Project00f06fc2009-03-03 19:32:15 -08002761 default: return "<unknown request>";
2762 }
2763}
2764
2765} /* namespace android */