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