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