ril.cpp
上传用户:rftzhifu
上传日期:2017-02-21
资源大小:229k
文件大小:60k
源码类别:

android开发

开发平台:

Unix_Linux

  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. #define LOG_TAG "RILC"
  18. #include <telephony/ril.h>
  19. #include <cutils/sockets.h>
  20. #include <cutils/jstring.h>
  21. #include <cutils/record_stream.h>
  22. #include <utils/Log.h>
  23. #include <utils/SystemClock.h>
  24. #include <pthread.h>
  25. #include <utils/Parcel.h>
  26. #include <cutils/jstring.h>
  27. #include <sys/types.h>
  28. #include <pwd.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <stdarg.h>
  32. #include <string.h>
  33. #include <unistd.h>
  34. #include <fcntl.h>
  35. #include <time.h>
  36. #include <errno.h>
  37. #include <assert.h>
  38. #include <ctype.h>
  39. #include <alloca.h>
  40. #include <sys/un.h>
  41. #include <assert.h>
  42. #include <netinet/in.h>
  43. #include <cutils/properties.h>
  44. #include <ril_event.h>
  45. namespace android {
  46. #define PHONE_PROCESS "radio"
  47. #define SOCKET_NAME_RIL "rild"
  48. #define SOCKET_NAME_RIL_DEBUG "rild-debug"
  49. #define ANDROID_WAKE_LOCK_NAME "radio-interface"
  50. #define ANDROID_PARTIAL_WAKE_LOCK_PATH "/sys/android_power/acquire_partial_wake_lock"
  51. #define ANDROID_FULL_WAKE_LOCK_PATH "/sys/android_power/acquire_full_wake_lock"
  52. #define ANDROID_WAKE_UNLOCK_PATH "/sys/android_power/release_wake_lock"
  53. #define PROPERTY_RIL_IMPL "gsm.version.ril-impl"
  54. // match with constant in RIL.java
  55. #define MAX_COMMAND_BYTES (8 * 1024)
  56. // Basically: memset buffers that the client library
  57. // shouldn't be using anymore in an attempt to find
  58. // memory usage issues sooner.
  59. #define MEMSET_FREED 1
  60. #define NUM_ELEMS(a)     (sizeof (a) / sizeof (a)[0])
  61. /* Constants for response types */
  62. #define RESPONSE_SOLICITED 0
  63. #define RESPONSE_UNSOLICITED 1
  64. /* Negative values for private RIL errno's */
  65. #define RIL_ERRNO_INVALID_RESPONSE -1
  66. // request, response, and unsolicited msg print macro
  67. #define PRINTBUF_SIZE 8096
  68. // Enable RILC log
  69. #define RILC_LOG 0
  70. #if RILC_LOG
  71.     #define startRequest           sprintf(printBuf, "(")
  72.     #define closeRequest           sprintf(printBuf, "%s)", printBuf)
  73.     #define printRequest(token, req)           
  74.             LOGD("[%04d]> %s %s", token, requestToString(req), printBuf)
  75.     #define startResponse           sprintf(printBuf, "%s {", printBuf)
  76.     #define closeResponse           sprintf(printBuf, "%s}", printBuf)
  77.     #define printResponse           LOGD("%s", printBuf)
  78.     #define clearPrintBuf           printBuf[0] = 0
  79.     #define removeLastChar          printBuf[strlen(printBuf)-1] = 0
  80.     #define appendPrintBuf(x...)    sprintf(printBuf, x)
  81. #else
  82.     #define startRequest
  83.     #define closeRequest
  84.     #define printRequest(token, req)
  85.     #define startResponse
  86.     #define closeResponse
  87.     #define printResponse
  88.     #define clearPrintBuf
  89.     #define removeLastChar
  90.     #define appendPrintBuf(x...)
  91. #endif
  92. enum WakeType {DONT_WAKE, WAKE_PARTIAL, WAKE_FULL};
  93. typedef struct {
  94.     int requestNumber;
  95.     void (*dispatchFunction) (Parcel &p, struct RequestInfo *pRI);
  96.     int(*responseFunction) (Parcel &p, void *response, size_t responselen);
  97. } CommandInfo;
  98. typedef struct {
  99.     int requestNumber;
  100.     int (*responseFunction) (Parcel &p, void *response, size_t responselen);
  101.     WakeType wakeType;
  102. } UnsolResponseInfo;
  103. typedef struct RequestInfo {
  104.     int32_t token;      //this is not RIL_Token 
  105.     CommandInfo *pCI;
  106.     struct RequestInfo *p_next;
  107.     char cancelled;
  108.     char local;         // responses to local commands do not go back to command process
  109. } RequestInfo;
  110. typedef struct UserCallbackInfo{
  111.     RIL_TimedCallback p_callback;
  112.     void *userParam;
  113.     struct ril_event event;
  114.     struct UserCallbackInfo *p_next;
  115. } UserCallbackInfo;
  116. /*******************************************************************/
  117. RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL};
  118. static int s_registerCalled = 0;
  119. static pthread_t s_tid_dispatch;
  120. static pthread_t s_tid_reader;
  121. static int s_started = 0;
  122. static int s_fdListen = -1;
  123. static int s_fdCommand = -1;
  124. static int s_fdDebug = -1;
  125. static int s_fdWakeupRead;
  126. static int s_fdWakeupWrite;
  127. static struct ril_event s_commands_event;
  128. static struct ril_event s_wakeupfd_event;
  129. static struct ril_event s_listen_event;
  130. static struct ril_event s_wake_timeout_event;
  131. static struct ril_event s_debug_event;
  132. static const struct timeval TIMEVAL_WAKE_TIMEOUT = {1,0};
  133. static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER;
  134. static pthread_mutex_t s_writeMutex = PTHREAD_MUTEX_INITIALIZER;
  135. static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
  136. static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER;
  137. static pthread_mutex_t s_dispatchMutex = PTHREAD_MUTEX_INITIALIZER;
  138. static pthread_cond_t s_dispatchCond = PTHREAD_COND_INITIALIZER;
  139. static RequestInfo *s_pendingRequests = NULL;
  140. static RequestInfo *s_toDispatchHead = NULL;
  141. static RequestInfo *s_toDispatchTail = NULL;
  142. static UserCallbackInfo *s_last_wake_timeout_info = NULL;
  143. static void *s_lastNITZTimeData = NULL;
  144. static size_t s_lastNITZTimeDataSize;
  145. #if RILC_LOG
  146.     static char printBuf[PRINTBUF_SIZE];
  147. #endif
  148. /*******************************************************************/
  149. static void dispatchVoid (Parcel& p, RequestInfo *pRI);
  150. static void dispatchString (Parcel& p, RequestInfo *pRI);
  151. static void dispatchStrings (Parcel& p, RequestInfo *pRI);
  152. static void dispatchInts (Parcel& p, RequestInfo *pRI);
  153. static void dispatchDial (Parcel& p, RequestInfo *pRI);
  154. static void dispatchSIM_IO (Parcel& p, RequestInfo *pRI);
  155. static void dispatchCallForward(Parcel& p, RequestInfo *pRI);
  156. static void dispatchRaw(Parcel& p, RequestInfo *pRI);
  157. static void dispatchSmsWrite (Parcel &p, RequestInfo *pRI);
  158. static int responseInts(Parcel &p, void *response, size_t responselen);
  159. static int responseStrings(Parcel &p, void *response, size_t responselen);
  160. static int responseString(Parcel &p, void *response, size_t responselen);
  161. static int responseVoid(Parcel &p, void *response, size_t responselen);
  162. static int responseCallList(Parcel &p, void *response, size_t responselen);
  163. static int responseSMS(Parcel &p, void *response, size_t responselen);
  164. static int responseSIM_IO(Parcel &p, void *response, size_t responselen);
  165. static int responseCallForwards(Parcel &p, void *response, size_t responselen);
  166. static int responseContexts(Parcel &p, void *response, size_t responselen);
  167. static int responseRaw(Parcel &p, void *response, size_t responselen);
  168. static int responseSsn(Parcel &p, void *response, size_t responselen);
  169. static int responseCellList(Parcel &p, void *response, size_t responselen);
  170. extern "C" const char * requestToString(int request);
  171. extern "C" const char * failCauseToString(RIL_Errno);
  172. extern "C" const char * callStateToString(RIL_CallState);
  173. extern "C" const char * radioStateToString(RIL_RadioState);
  174. #ifdef RIL_SHLIB
  175. extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, void *data, 
  176.                                 size_t datalen);
  177. #endif
  178. static UserCallbackInfo * internalRequestTimedCallback 
  179.     (RIL_TimedCallback callback, void *param, 
  180.         const struct timeval *relativeTime);
  181. /** Index == requestNumber */
  182. static CommandInfo s_commands[] = {
  183. #include "ril_commands.h"
  184. };
  185. static UnsolResponseInfo s_unsolResponses[] = {
  186. #include "ril_unsol_commands.h"
  187. };
  188. static char *
  189. strdupReadString(Parcel &p)
  190. {
  191.     size_t stringlen;
  192.     const char16_t *s16;
  193.             
  194.     s16 = p.readString16Inplace(&stringlen);
  195.     
  196.     return strndup16to8(s16, stringlen);
  197. }
  198. static void writeStringToParcel(Parcel &p, const char *s)
  199. {
  200.     char16_t *s16;
  201.     size_t s16_len;
  202.     s16 = strdup8to16(s, &s16_len);
  203.     p.writeString16(s16, s16_len);
  204.     free(s16);
  205. }
  206. static void
  207. memsetString (char *s)
  208. {
  209.     if (s != NULL) {
  210.         memset (s, 0, strlen(s));
  211.     }
  212. }
  213. void   nullParcelReleaseFunction (const uint8_t* data, size_t dataSize,
  214.                                     const size_t* objects, size_t objectsSize,
  215.                                         void* cookie)
  216. {
  217.     // do nothing -- the data reference lives longer than the Parcel object
  218. }
  219. /** 
  220.  * To be called from dispatch thread
  221.  * Issue a single local request, ensuring that the response
  222.  * is not sent back up to the command process 
  223.  */
  224. static void
  225. issueLocalRequest(int request, void *data, int len)
  226. {
  227.     RequestInfo *pRI;
  228.     int ret;
  229.     pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
  230.     pRI->local = 1;
  231.     pRI->token = 0xffffffff;        // token is not used in this context
  232.     pRI->pCI = &(s_commands[request]);
  233.     ret = pthread_mutex_lock(&s_pendingRequestsMutex);
  234.     assert (ret == 0);
  235.     pRI->p_next = s_pendingRequests;
  236.     s_pendingRequests = pRI;
  237.     ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
  238.     assert (ret == 0);
  239.     LOGD("C[locl]> %s", requestToString(request));
  240.     s_callbacks.onRequest(request, data, len, pRI);
  241. }
  242. static int
  243. processCommandBuffer(void *buffer, size_t buflen)
  244. {
  245.     Parcel p;
  246.     status_t status;
  247.     int32_t request;
  248.     int32_t token;
  249.     RequestInfo *pRI;
  250.     int ret;
  251.     p.setData((uint8_t *) buffer, buflen);
  252.     // status checked at end
  253.     status = p.readInt32(&request);
  254.     status = p.readInt32 (&token);
  255.     if (status != NO_ERROR) {
  256.         LOGE("invalid request block");
  257.         return 0;
  258.     }
  259.     if (request < 1 || request >= (int32_t)NUM_ELEMS(s_commands)) {
  260.         LOGE("unsupported request code %d token %d", request, token);
  261.         // FIXME this should perhaps return a response
  262.         return 0;
  263.     }
  264.     pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
  265.     pRI->token = token;
  266.     pRI->pCI = &(s_commands[request]);
  267.     ret = pthread_mutex_lock(&s_pendingRequestsMutex);
  268.     assert (ret == 0);
  269.     pRI->p_next = s_pendingRequests;
  270.     s_pendingRequests = pRI;
  271.     ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
  272.     assert (ret == 0);
  273. /*    sLastDispatchedToken = token; */
  274.     pRI->pCI->dispatchFunction(p, pRI);    
  275.     return 0;
  276. }
  277. static void
  278. invalidCommandBlock (RequestInfo *pRI)
  279. {
  280.     LOGE("invalid command block for token %d request %s", 
  281.                 pRI->token, requestToString(pRI->pCI->requestNumber));
  282. }
  283. /** Callee expects NULL */
  284. static void 
  285. dispatchVoid (Parcel& p, RequestInfo *pRI)
  286. {
  287.     clearPrintBuf;
  288.     printRequest(pRI->token, pRI->pCI->requestNumber);
  289.     s_callbacks.onRequest(pRI->pCI->requestNumber, NULL, 0, pRI);
  290. }
  291. /** Callee expects const char * */
  292. static void
  293. dispatchString (Parcel& p, RequestInfo *pRI)
  294. {
  295.     status_t status;
  296.     size_t datalen;
  297.     size_t stringlen;
  298.     char *string8 = NULL;
  299.     string8 = strdupReadString(p);
  300.     startRequest;
  301.     appendPrintBuf("%s%s", printBuf, string8);
  302.     closeRequest;
  303.     printRequest(pRI->token, pRI->pCI->requestNumber);
  304.     s_callbacks.onRequest(pRI->pCI->requestNumber, string8,
  305.                        sizeof(char *), pRI);
  306. #ifdef MEMSET_FREED
  307.     memsetString(string8);
  308. #endif
  309.     free(string8);
  310.     return;
  311. invalid:
  312.     invalidCommandBlock(pRI);
  313.     return;
  314. }
  315. /** Callee expects const char ** */
  316. static void
  317. dispatchStrings (Parcel &p, RequestInfo *pRI)
  318. {
  319.     int32_t countStrings;
  320.     status_t status;
  321.     size_t datalen;
  322.     char **pStrings;
  323.     status = p.readInt32 (&countStrings);
  324.     if (status != NO_ERROR) {
  325.         goto invalid;
  326.     }
  327.     startRequest;
  328.     if (countStrings == 0) {
  329.         // just some non-null pointer
  330.         pStrings = (char **)alloca(sizeof(char *));
  331.         datalen = 0;
  332.     } else if (((int)countStrings) == -1) {
  333.         pStrings = NULL;
  334.         datalen = 0;
  335.     } else {
  336.         datalen = sizeof(char *) * countStrings;
  337.     
  338.         pStrings = (char **)alloca(datalen);
  339.         for (int i = 0 ; i < countStrings ; i++) {
  340.             pStrings[i] = strdupReadString(p);
  341.             appendPrintBuf("%s%s,", printBuf, pStrings[i]);
  342.         }
  343.     }
  344.     removeLastChar;
  345.     closeRequest;
  346.     printRequest(pRI->token, pRI->pCI->requestNumber);
  347.     s_callbacks.onRequest(pRI->pCI->requestNumber, pStrings, datalen, pRI);
  348.     if (pStrings != NULL) {
  349.         for (int i = 0 ; i < countStrings ; i++) {
  350. #ifdef MEMSET_FREED
  351.             memsetString (pStrings[i]);
  352. #endif
  353.             free(pStrings[i]);
  354.         }
  355. #ifdef MEMSET_FREED
  356.         memset(pStrings, 0, datalen);
  357. #endif
  358.     }
  359.     
  360.     return;
  361. invalid:
  362.     invalidCommandBlock(pRI);
  363.     return;
  364. }
  365. /** Callee expects const int * */
  366. static void
  367. dispatchInts (Parcel &p, RequestInfo *pRI)
  368. {
  369.     int32_t count;
  370.     status_t status;
  371.     size_t datalen;
  372.     int *pInts;
  373.     status = p.readInt32 (&count);
  374.     if (status != NO_ERROR || count == 0) {
  375.         goto invalid;
  376.     }
  377.     datalen = sizeof(int) * count;
  378.     pInts = (int *)alloca(datalen);
  379.     startRequest;
  380.     for (int i = 0 ; i < count ; i++) {
  381.         int32_t t;
  382.         status = p.readInt32(&t);
  383.         pInts[i] = (int)t;
  384.         appendPrintBuf("%s%d,", printBuf, t);
  385.         if (status != NO_ERROR) {
  386.             goto invalid;
  387.         }
  388.    }
  389.    removeLastChar;
  390.    closeRequest;
  391.    printRequest(pRI->token, pRI->pCI->requestNumber);
  392.    s_callbacks.onRequest(pRI->pCI->requestNumber, const_cast<int *>(pInts), 
  393.                        datalen, pRI);
  394. #ifdef MEMSET_FREED
  395.     memset(pInts, 0, datalen);
  396. #endif
  397.     return;
  398. invalid:
  399.     invalidCommandBlock(pRI);
  400.     return;
  401. }
  402. /** 
  403.  * Callee expects const RIL_SMS_WriteArgs * 
  404.  * Payload is:
  405.  *   int32_t status
  406.  *   String pdu
  407.  */
  408. static void
  409. dispatchSmsWrite (Parcel &p, RequestInfo *pRI)
  410. {
  411.     RIL_SMS_WriteArgs args;
  412.     int32_t t;
  413.     status_t status;
  414.     memset (&args, 0, sizeof(args));
  415.     status = p.readInt32(&t);
  416.     args.status = (int)t;
  417.     args.pdu = strdupReadString(p);
  418.     if (status != NO_ERROR || args.pdu == NULL) {
  419.         goto invalid;
  420.     }
  421.     args.smsc = strdupReadString(p);
  422.     startRequest;
  423.     appendPrintBuf("%s%d,%s,smsc=%s", printBuf, args.status,
  424.         (char*)args.pdu,  (char*)args.smsc);
  425.     closeRequest;
  426.     printRequest(pRI->token, pRI->pCI->requestNumber);
  427.     
  428.     s_callbacks.onRequest(pRI->pCI->requestNumber, &args, sizeof(args), pRI);
  429. #ifdef MEMSET_FREED
  430.     memsetString (args.pdu);
  431. #endif
  432.     free (args.pdu);
  433.     
  434. #ifdef MEMSET_FREED
  435.     memset(&args, 0, sizeof(args));
  436. #endif
  437.     return;
  438. invalid:
  439.     invalidCommandBlock(pRI);
  440.     return;
  441. }
  442. /** 
  443.  * Callee expects const RIL_Dial * 
  444.  * Payload is:
  445.  *   String address
  446.  *   int32_t clir
  447.  */
  448. static void
  449. dispatchDial (Parcel &p, RequestInfo *pRI)
  450. {
  451.     RIL_Dial dial;
  452.     int32_t t;
  453.     status_t status;
  454.     memset (&dial, 0, sizeof(dial));
  455.     dial.address = strdupReadString(p);
  456.     status = p.readInt32(&t);
  457.     dial.clir = (int)t;
  458.     if (status != NO_ERROR || dial.address == NULL) {
  459.         goto invalid;
  460.     }
  461.     startRequest;
  462.     appendPrintBuf("%snum=%s,clir=%d", printBuf, dial.address, dial.clir);
  463.     closeRequest;
  464.     printRequest(pRI->token, pRI->pCI->requestNumber);
  465.     s_callbacks.onRequest(pRI->pCI->requestNumber, &dial, sizeof(dial), pRI);
  466. #ifdef MEMSET_FREED
  467.     memsetString (dial.address);
  468. #endif
  469.     free (dial.address);
  470.     
  471. #ifdef MEMSET_FREED
  472.     memset(&dial, 0, sizeof(dial));
  473. #endif
  474.     return;
  475. invalid:
  476.     invalidCommandBlock(pRI);
  477.     return;
  478. }
  479. /** 
  480.  * Callee expects const RIL_SIM_IO * 
  481.  * Payload is:
  482.  *   int32_t command
  483.  *   int32_t fileid
  484.  *   String path
  485.  *   int32_t p1, p2, p3
  486.  *   String data 
  487.  *   String pin2 
  488.  */
  489. static void
  490. dispatchSIM_IO (Parcel &p, RequestInfo *pRI)
  491. {
  492.     RIL_SIM_IO simIO;
  493.     int32_t t;
  494.     status_t status;
  495.     memset (&simIO, 0, sizeof(simIO));
  496.     // note we only check status at the end 
  497.     
  498.     status = p.readInt32(&t);
  499.     simIO.command = (int)t;
  500.     status = p.readInt32(&t);
  501.     simIO.fileid = (int)t;
  502.     simIO.path = strdupReadString(p);
  503.     status = p.readInt32(&t);
  504.     simIO.p1 = (int)t;
  505.     status = p.readInt32(&t);
  506.     simIO.p2 = (int)t;
  507.     status = p.readInt32(&t);
  508.     simIO.p3 = (int)t;
  509.     simIO.data = strdupReadString(p);
  510.     simIO.pin2 = strdupReadString(p);
  511.     startRequest;
  512.     appendPrintBuf("%scmd=0x%X,efid=0x%X,path=%s,%d,%d,%d,%s,pin2=%s", printBuf,
  513.         simIO.command, simIO.fileid, (char*)simIO.path,
  514.         simIO.p1, simIO.p2, simIO.p3,
  515.         (char*)simIO.data,  (char*)simIO.pin2);
  516.     closeRequest;
  517.     printRequest(pRI->token, pRI->pCI->requestNumber);
  518.     
  519.     if (status != NO_ERROR) {
  520.         goto invalid;
  521.     }
  522.        s_callbacks.onRequest(pRI->pCI->requestNumber, &simIO, sizeof(simIO), pRI);
  523. #ifdef MEMSET_FREED
  524.     memsetString (simIO.path);
  525.     memsetString (simIO.data);
  526.     memsetString (simIO.pin2);
  527. #endif
  528.     free (simIO.path);
  529.     free (simIO.data);
  530.     free (simIO.pin2);
  531.     
  532. #ifdef MEMSET_FREED
  533.     memset(&simIO, 0, sizeof(simIO));
  534. #endif
  535.     return;
  536. invalid:
  537.     invalidCommandBlock(pRI);
  538.     return;
  539. }
  540. /**
  541.  * Callee expects const RIL_CallForwardInfo *
  542.  * Payload is:
  543.  *  int32_t status/action
  544.  *  int32_t reason
  545.  *  int32_t serviceCode
  546.  *  int32_t toa
  547.  *  String number  (0 length -> null)
  548.  *  int32_t timeSeconds
  549.  */
  550. static void 
  551. dispatchCallForward(Parcel &p, RequestInfo *pRI)
  552. {
  553.     RIL_CallForwardInfo cff;
  554.     int32_t t;
  555.     status_t status;
  556.     memset (&cff, 0, sizeof(cff));
  557.     // note we only check status at the end 
  558.     status = p.readInt32(&t);
  559.     cff.status = (int)t;
  560.     
  561.     status = p.readInt32(&t);
  562.     cff.reason = (int)t;
  563.     status = p.readInt32(&t);
  564.     cff.serviceClass = (int)t;
  565.     status = p.readInt32(&t);
  566.     cff.toa = (int)t;
  567.     cff.number = strdupReadString(p);
  568.     status = p.readInt32(&t);
  569.     cff.timeSeconds = (int)t;
  570.     if (status != NO_ERROR) {
  571.         goto invalid;
  572.     }
  573.     // special case: number 0-length fields is null
  574.     if (cff.number != NULL && strlen (cff.number) == 0) {
  575.         cff.number = NULL;
  576.     }
  577.     startRequest;
  578.     appendPrintBuf("%sstat=%d,reason=%d,serv=%d,toa=%d,%s,tout=%d", printBuf,
  579.         cff.status, cff.reason, cff.serviceClass, cff.toa,
  580.         (char*)cff.number, cff.timeSeconds);
  581.     closeRequest;
  582.     printRequest(pRI->token, pRI->pCI->requestNumber);
  583.     s_callbacks.onRequest(pRI->pCI->requestNumber, &cff, sizeof(cff), pRI);
  584. #ifdef MEMSET_FREED
  585.     memsetString(cff.number);
  586. #endif
  587.     free (cff.number);
  588. #ifdef MEMSET_FREED
  589.     memset(&cff, 0, sizeof(cff));
  590. #endif
  591.     return;
  592. invalid:
  593.     invalidCommandBlock(pRI);
  594.     return;
  595. }
  596. static void 
  597. dispatchRaw(Parcel &p, RequestInfo *pRI)
  598. {
  599.     int32_t len;
  600.     status_t status;
  601.     const void *data;
  602.     status = p.readInt32(&len);
  603.     if (status != NO_ERROR) {
  604.         goto invalid;
  605.     }
  606.     // The java code writes -1 for null arrays
  607.     if (((int)len) == -1) {
  608.         data = NULL;
  609.         len = 0;
  610.     } 
  611.     data = p.readInplace(len);
  612.     startRequest;
  613.     appendPrintBuf("%sraw_size=%d", printBuf, len);
  614.     closeRequest;
  615.     printRequest(pRI->token, pRI->pCI->requestNumber);
  616.     s_callbacks.onRequest(pRI->pCI->requestNumber, const_cast<void *>(data), len, pRI);
  617.     return;
  618. invalid:
  619.     invalidCommandBlock(pRI);
  620.     return;
  621. }
  622. static int
  623. blockingWrite(int fd, const void *buffer, size_t len)
  624. {
  625.     size_t writeOffset = 0; 
  626.     const uint8_t *toWrite;
  627.     toWrite = (const uint8_t *)buffer;
  628.     while (writeOffset < len) {
  629.         ssize_t written;
  630.         do {
  631.             written = write (fd, toWrite + writeOffset,
  632.                                 len - writeOffset);
  633.         } while (written < 0 && errno == EINTR);
  634.         if (written >= 0) {
  635.             writeOffset += written;
  636.         } else {   // written < 0
  637.             LOGE ("RIL Response: unexpected error on write errno:%d", errno);
  638.             close(fd);
  639.             return -1;
  640.         }
  641.     }
  642.     return 0;
  643. }
  644. static int
  645. sendResponseRaw (const void *data, size_t dataSize)
  646. {
  647.     int fd = s_fdCommand;
  648.     int ret;
  649.     uint32_t header;
  650.     if (s_fdCommand < 0) {
  651.         return -1;
  652.     }
  653.     if (dataSize > MAX_COMMAND_BYTES) {
  654.         LOGE("RIL: packet larger than %u (%u)",
  655.                 MAX_COMMAND_BYTES, (unsigned int )dataSize);
  656.         return -1;
  657.     }
  658.     
  659.     // FIXME is blocking here ok? issue #550970
  660.     pthread_mutex_lock(&s_writeMutex);
  661.     header = htonl(dataSize);
  662.     ret = blockingWrite(fd, (void *)&header, sizeof(header));
  663.     if (ret < 0) {
  664.         return ret;
  665.     }
  666.     blockingWrite(fd, data, dataSize);
  667.     if (ret < 0) {
  668.         return ret;
  669.     }
  670.     pthread_mutex_unlock(&s_writeMutex);
  671.     return 0;
  672. }
  673. static int
  674. sendResponse (Parcel &p)
  675. {
  676.     printResponse;
  677.     return sendResponseRaw(p.data(), p.dataSize());
  678. }
  679. /** response is an int* pointing to an array of ints*/
  680.  
  681. static int 
  682. responseInts(Parcel &p, void *response, size_t responselen)
  683. {
  684.     int numInts;
  685.     if (response == NULL && responselen != 0) {
  686.         LOGE("invalid response: NULL");
  687.         return RIL_ERRNO_INVALID_RESPONSE;
  688.     }
  689.     if (responselen % sizeof(int) != 0) {
  690.         LOGE("invalid response length %d expected multiple of %dn", 
  691.             (int)responselen, (int)sizeof(int));
  692.         return RIL_ERRNO_INVALID_RESPONSE;
  693.     }
  694.     int *p_int = (int *) response;
  695.     numInts = responselen / sizeof(int *);
  696.     p.writeInt32 (numInts);
  697.     /* each int*/
  698.     startResponse;
  699.     for (int i = 0 ; i < numInts ; i++) {
  700.         appendPrintBuf("%s%d,", printBuf, p_int[i]);
  701.         p.writeInt32(p_int[i]);
  702.     }
  703.     removeLastChar;
  704.     closeResponse;
  705.     return 0;
  706. }
  707. /** response is a char **, pointing to an array of char *'s */
  708. static int responseStrings(Parcel &p, void *response, size_t responselen)
  709. {
  710.     int numStrings;
  711.     
  712.     if (response == NULL && responselen != 0) {
  713.         LOGE("invalid response: NULL");
  714.         return RIL_ERRNO_INVALID_RESPONSE;
  715.     }
  716.     if (responselen % sizeof(char *) != 0) {
  717.         LOGE("invalid response length %d expected multiple of %dn", 
  718.             (int)responselen, (int)sizeof(char *));
  719.         return RIL_ERRNO_INVALID_RESPONSE;
  720.     }
  721.     if (response == NULL) {
  722.         p.writeInt32 (0);
  723.     } else {
  724.         char **p_cur = (char **) response;
  725.         numStrings = responselen / sizeof(char *);
  726.         p.writeInt32 (numStrings);
  727.         /* each string*/
  728.         startResponse;
  729.         for (int i = 0 ; i < numStrings ; i++) {
  730.             appendPrintBuf("%s%s,", printBuf, (char*)p_cur[i]);
  731.             writeStringToParcel (p, p_cur[i]);
  732.         }
  733.         removeLastChar;
  734.         closeResponse;
  735.     }
  736.     return 0;
  737. }
  738. /**
  739.  * NULL strings are accepted 
  740.  * FIXME currently ignores responselen
  741.  */
  742. static int responseString(Parcel &p, void *response, size_t responselen)
  743. {
  744.     /* one string only */
  745.     startResponse;
  746.     appendPrintBuf("%s%s", printBuf, (char*)response);
  747.     closeResponse;
  748.     writeStringToParcel(p, (const char *)response);
  749.     return 0;
  750. }
  751. static int responseVoid(Parcel &p, void *response, size_t responselen)
  752. {
  753.     startResponse;
  754.     removeLastChar;
  755.     return 0;
  756. }
  757. static int responseCallList(Parcel &p, void *response, size_t responselen)
  758. {    
  759.     int num;
  760.     if (response == NULL && responselen != 0) {
  761.         LOGE("invalid response: NULL");
  762.         return RIL_ERRNO_INVALID_RESPONSE;
  763.     }
  764.     if (responselen % sizeof (RIL_Call *) != 0) {
  765.         LOGE("invalid response length %d expected multiple of %dn", 
  766.             (int)responselen, (int)sizeof (RIL_Call *));
  767.         return RIL_ERRNO_INVALID_RESPONSE;
  768.     }
  769.     startResponse;
  770.     /* number of call info's */
  771.     num = responselen / sizeof(RIL_Call *);
  772.     p.writeInt32(num);
  773.     for (int i = 0 ; i < num ; i++) {
  774.         RIL_Call *p_cur = ((RIL_Call **) response)[i];
  775.         /* each call info */
  776.         p.writeInt32(p_cur->state);
  777.         p.writeInt32(p_cur->index);
  778.         p.writeInt32(p_cur->toa);
  779.         p.writeInt32(p_cur->isMpty);
  780.         p.writeInt32(p_cur->isMT);
  781.         p.writeInt32(p_cur->als);
  782.         p.writeInt32(p_cur->isVoice);
  783.         writeStringToParcel (p, p_cur->number);
  784.         appendPrintBuf("%s[%s,id=%d,toa=%d,%s,%s,als=%d,%s,%s],", printBuf,
  785.             callStateToString(p_cur->state),
  786.             p_cur->index, p_cur->toa,
  787.             (p_cur->isMpty)?"mpty":"norm",
  788.             (p_cur->isMT)?"mt":"mo",
  789.             p_cur->als,
  790.             (p_cur->isVoice)?"voc":"nonvoc",
  791.             (char*)p_cur->number);
  792.     }
  793.     removeLastChar;
  794.     closeResponse;
  795.     return 0;
  796. }
  797. static int responseSMS(Parcel &p, void *response, size_t responselen)
  798. {
  799.     if (response == NULL) {
  800.         LOGE("invalid response: NULL");
  801.         return RIL_ERRNO_INVALID_RESPONSE;
  802.     }
  803.     if (responselen != sizeof (RIL_SMS_Response) ) {
  804.         LOGE("invalid response length %d expected %d", 
  805.                 (int)responselen, (int)sizeof (RIL_SMS_Response));
  806.         return RIL_ERRNO_INVALID_RESPONSE;
  807.     }
  808.     RIL_SMS_Response *p_cur = (RIL_SMS_Response *) response;
  809.     p.writeInt32(p_cur->messageRef);
  810.     writeStringToParcel(p, p_cur->ackPDU);
  811.     startResponse;
  812.     appendPrintBuf("%s%d,%s", printBuf, p_cur->messageRef,
  813.         (char*)p_cur->ackPDU);
  814.     closeResponse;
  815.     return 0;
  816. }
  817. static int responseContexts(Parcel &p, void *response, size_t responselen)
  818. {
  819.     if (response == NULL && responselen != 0) {
  820.         LOGE("invalid response: NULL");
  821.         return RIL_ERRNO_INVALID_RESPONSE;
  822.     }
  823.     if (responselen % sizeof(RIL_PDP_Context_Response) != 0) {
  824.         LOGE("invalid response length %d expected multiple of %d", 
  825.                 (int)responselen, (int)sizeof(RIL_PDP_Context_Response));
  826.         return RIL_ERRNO_INVALID_RESPONSE;
  827.     }
  828.     int num = responselen / sizeof(RIL_PDP_Context_Response);
  829.     p.writeInt32(num);
  830.     RIL_PDP_Context_Response *p_cur = (RIL_PDP_Context_Response *) response;
  831.     startResponse;
  832.     int i;
  833.     for (i = 0; i < num; i++) {
  834.         p.writeInt32(p_cur[i].cid);
  835.         p.writeInt32(p_cur[i].active);
  836.         writeStringToParcel(p, p_cur[i].type);
  837.         writeStringToParcel(p, p_cur[i].apn);
  838.         writeStringToParcel(p, p_cur[i].address);
  839.         appendPrintBuf("%s[cid=%d,%s,%s,%s,%s],", printBuf,
  840.             p_cur[i].cid,
  841.             (p_cur[i].active==0)?"down":"up",
  842.             (char*)p_cur[i].type,
  843.             (char*)p_cur[i].apn,
  844.             (char*)p_cur[i].address);
  845.     }
  846.     removeLastChar;
  847.     closeResponse;
  848.     return 0;
  849. }
  850. static int responseRaw(Parcel &p, void *response, size_t responselen)
  851. {
  852.     if (response == NULL && responselen != 0) {
  853.         LOGE("invalid response: NULL with responselen != 0");
  854.         return RIL_ERRNO_INVALID_RESPONSE;
  855.     }
  856.     // The java code reads -1 size as null byte array
  857.     if (response == NULL) {
  858.         p.writeInt32(-1);       
  859.     } else {
  860.         p.writeInt32(responselen);
  861.         p.write(response, responselen);
  862.     }
  863.     return 0;
  864. }
  865. static int responseSIM_IO(Parcel &p, void *response, size_t responselen)
  866. {
  867.     if (response == NULL) {
  868.         LOGE("invalid response: NULL");
  869.         return RIL_ERRNO_INVALID_RESPONSE;
  870.     }
  871.     if (responselen != sizeof (RIL_SIM_IO_Response) ) {
  872.         LOGE("invalid response length was %d expected %d",
  873.                 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
  874.         return RIL_ERRNO_INVALID_RESPONSE;
  875.     }
  876.     RIL_SIM_IO_Response *p_cur = (RIL_SIM_IO_Response *) response;
  877.     p.writeInt32(p_cur->sw1);
  878.     p.writeInt32(p_cur->sw2);
  879.     writeStringToParcel(p, p_cur->simResponse);
  880.     startResponse;
  881.     appendPrintBuf("%ssw1=0x%X,sw2=0x%X,%s", printBuf, p_cur->sw1, p_cur->sw2,
  882.         (char*)p_cur->simResponse);
  883.     closeResponse;
  884.     return 0;
  885. }
  886. static int responseCallForwards(Parcel &p, void *response, size_t responselen)
  887. {
  888.     int num;
  889.     
  890.     if (response == NULL && responselen != 0) {
  891.         LOGE("invalid response: NULL");
  892.         return RIL_ERRNO_INVALID_RESPONSE;
  893.     }
  894.     if (responselen % sizeof(RIL_CallForwardInfo *) != 0) {
  895.         LOGE("invalid response length %d expected multiple of %d", 
  896.                 (int)responselen, (int)sizeof(RIL_CallForwardInfo *));
  897.         return RIL_ERRNO_INVALID_RESPONSE;
  898.     }
  899.     /* number of call info's */
  900.     num = responselen / sizeof(RIL_CallForwardInfo *);
  901.     p.writeInt32(num);
  902.     startResponse;
  903.     for (int i = 0 ; i < num ; i++) {
  904.         RIL_CallForwardInfo *p_cur = ((RIL_CallForwardInfo **) response)[i];
  905.         p.writeInt32(p_cur->status);
  906.         p.writeInt32(p_cur->reason);
  907.         p.writeInt32(p_cur->serviceClass);
  908.         p.writeInt32(p_cur->toa);
  909.         writeStringToParcel(p, p_cur->number);
  910.         p.writeInt32(p_cur->timeSeconds);
  911.         appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
  912.             (p_cur->status==1)?"enable":"disable",
  913.             p_cur->reason, p_cur->serviceClass, p_cur->toa,
  914.             (char*)p_cur->number,
  915.             p_cur->timeSeconds);
  916.     }
  917.     removeLastChar;
  918.     closeResponse;
  919.     
  920.     return 0;
  921. }
  922. static int responseSsn(Parcel &p, void *response, size_t responselen)
  923. {
  924.     if (response == NULL) {
  925.         LOGE("invalid response: NULL");
  926.         return RIL_ERRNO_INVALID_RESPONSE;
  927.     }
  928.     if (responselen != sizeof(RIL_SuppSvcNotification)) {
  929.         LOGE("invalid response length was %d expected %d",
  930.                 (int)responselen, (int)sizeof (RIL_SuppSvcNotification));
  931.         return RIL_ERRNO_INVALID_RESPONSE;
  932.     }
  933.     RIL_SuppSvcNotification *p_cur = (RIL_SuppSvcNotification *) response;
  934.     p.writeInt32(p_cur->notificationType);
  935.     p.writeInt32(p_cur->code);
  936.     p.writeInt32(p_cur->index);
  937.     p.writeInt32(p_cur->type);
  938.     writeStringToParcel(p, p_cur->number);
  939.     startResponse;
  940.     appendPrintBuf("%s%s,code=%d,id=%d,type=%d,%s", printBuf,
  941.         (p_cur->notificationType==0)?"mo":"mt",
  942.          p_cur->code, p_cur->index, p_cur->type,
  943.         (char*)p_cur->number);
  944.     closeResponse;
  945.     return 0;
  946. }
  947. static int responseCellList(Parcel &p, void *response, size_t responselen)
  948. {
  949.     int num;
  950.     if (response == NULL && responselen != 0) {
  951.         LOGE("invalid response: NULL");
  952.         return RIL_ERRNO_INVALID_RESPONSE;
  953.     }
  954.     if (responselen % sizeof (RIL_NeighboringCell *) != 0) {
  955.         LOGE("invalid response length %d expected multiple of %dn",
  956.             (int)responselen, (int)sizeof (RIL_NeighboringCell *));
  957.         return RIL_ERRNO_INVALID_RESPONSE;
  958.     }
  959.     startResponse;
  960.     /* number of cell info's */
  961.     num = responselen / sizeof(RIL_NeighboringCell *);
  962.     p.writeInt32(num);
  963.     for (int i = 0 ; i < num ; i++) {
  964.         RIL_NeighboringCell *p_cur = ((RIL_NeighboringCell **) response)[i];
  965.         /* each cell info */
  966.         p.writeInt32(p_cur->rssi);
  967.         writeStringToParcel (p, p_cur->cid);
  968.         appendPrintBuf("%s[cid=%s,rssi=%d],", printBuf,
  969.             p_cur->cid, p_cur->rssi);
  970.     }
  971.     removeLastChar;
  972.     closeResponse;
  973.     return 0;
  974. }
  975. static void triggerEvLoop()
  976. {
  977.     int ret;
  978.     if (!pthread_equal(pthread_self(), s_tid_dispatch)) {
  979.         /* trigger event loop to wakeup. No reason to do this,
  980.          * if we're in the event loop thread */
  981.          do {
  982.             ret = write (s_fdWakeupWrite, " ", 1);
  983.          } while (ret < 0 && errno == EINTR);
  984.     }
  985. }
  986. static void rilEventAddWakeup(struct ril_event *ev)
  987. {
  988.     ril_event_add(ev);
  989.     triggerEvLoop();
  990. }
  991. /**
  992.  * A write on the wakeup fd is done just to pop us out of select()
  993.  * We empty the buffer here and then ril_event will reset the timers on the
  994.  * way back down
  995.  */
  996. static void processWakeupCallback(int fd, short flags, void *param)
  997. {
  998.     char buff[16];
  999.     int ret;
  1000.     LOGV("processWakeupCallback");
  1001.     /* empty our wakeup socket out */
  1002.     do {
  1003.         ret = read(s_fdWakeupRead, &buff, sizeof(buff));
  1004.     } while (ret > 0 || (ret < 0 && errno == EINTR)); 
  1005. }
  1006. static void onCommandsSocketClosed()
  1007. {
  1008.     int ret;
  1009.     RequestInfo *p_cur;
  1010.     /* mark pending requests as "cancelled" so we dont report responses */
  1011.     ret = pthread_mutex_lock(&s_pendingRequestsMutex);
  1012.     assert (ret == 0);
  1013.     p_cur = s_pendingRequests;
  1014.     for (p_cur = s_pendingRequests 
  1015.             ; p_cur != NULL
  1016.             ; p_cur  = p_cur->p_next
  1017.     ) {
  1018.         p_cur->cancelled = 1;
  1019.     }
  1020.     ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
  1021.     assert (ret == 0);
  1022. }
  1023. static void processCommandsCallback(int fd, short flags, void *param)
  1024. {
  1025.     RecordStream *p_rs;
  1026.     void *p_record;
  1027.     size_t recordlen;
  1028.     int ret;
  1029.     assert(fd == s_fdCommand);
  1030.     p_rs = (RecordStream *)param;
  1031.     for (;;) {
  1032.         /* loop until EAGAIN/EINTR, end of stream, or other error */
  1033.         ret = record_stream_get_next(p_rs, &p_record, &recordlen);
  1034.         if (ret == 0 && p_record == NULL) {
  1035.             /* end-of-stream */
  1036.             break;
  1037.         } else if (ret < 0) {
  1038.             break;
  1039.         } else if (ret == 0) { /* && p_record != NULL */
  1040.             processCommandBuffer(p_record, recordlen);
  1041.         }
  1042.     }
  1043.     if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) {
  1044.         /* fatal error or end-of-stream */
  1045.         if (ret != 0) {
  1046.             LOGE("error on reading command socket errno:%dn", errno);
  1047.         } else {
  1048.             LOGW("EOS.  Closing command socket.");
  1049.         }
  1050.         
  1051.         close(s_fdCommand);
  1052.         s_fdCommand = -1;
  1053.         ril_event_del(&s_commands_event);
  1054.         record_stream_free(p_rs);
  1055.         /* start listening for new connections again */
  1056.         rilEventAddWakeup(&s_listen_event);
  1057.         onCommandsSocketClosed();
  1058.     }
  1059. }
  1060. static void onNewCommandConnect()
  1061. {
  1062.     // implicit radio state changed
  1063.     RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
  1064.                                     NULL, 0);
  1065.     // Send last NITZ time data, in case it was missed
  1066.     if (s_lastNITZTimeData != NULL) {
  1067.         sendResponseRaw(s_lastNITZTimeData, s_lastNITZTimeDataSize);
  1068.         free(s_lastNITZTimeData);
  1069.         s_lastNITZTimeData = NULL;
  1070.     }
  1071.     // Get version string
  1072.     if (s_callbacks.getVersion != NULL) {
  1073.         const char *version;
  1074.         version = s_callbacks.getVersion();
  1075.         LOGI("RIL Daemon version: %sn", version);
  1076.         
  1077.         property_set(PROPERTY_RIL_IMPL, version);
  1078.     } else {
  1079.         LOGI("RIL Daemon version: unavailablen");
  1080.         property_set(PROPERTY_RIL_IMPL, "unavailable");
  1081.     }
  1082. }
  1083. static void listenCallback (int fd, short flags, void *param)
  1084. {
  1085.     int ret;
  1086.     int err;
  1087.     int is_phone_socket;
  1088.     RecordStream *p_rs;
  1089.     struct sockaddr_un peeraddr;
  1090.     socklen_t socklen = sizeof (peeraddr);
  1091.     struct ucred creds;
  1092.     socklen_t szCreds = sizeof(creds);
  1093.     struct passwd *pwd = NULL;
  1094.     assert (s_fdCommand < 0);
  1095.     assert (fd == s_fdListen);
  1096.     
  1097.     s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);
  1098.     if (s_fdCommand < 0 ) {
  1099.         LOGE("Error on accept() errno:%d", errno);
  1100.         /* start listening for new connections again */
  1101.         rilEventAddWakeup(&s_listen_event);
  1102. return;
  1103.     }
  1104.     /* check the credential of the other side and only accept socket from
  1105.      * phone process
  1106.      */ 
  1107.     errno = 0;
  1108.     is_phone_socket = 0;
  1109.     
  1110.     err = getsockopt(s_fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds);
  1111.     
  1112.     if (err == 0 && szCreds > 0) {
  1113.       errno = 0;
  1114.       pwd = getpwuid(creds.uid);
  1115.       if (pwd != NULL) {
  1116. if (strcmp(pwd->pw_name, PHONE_PROCESS) == 0) {
  1117.   is_phone_socket = 1;
  1118. } else {
  1119.   LOGE("RILD can't accept socket from process %s", pwd->pw_name);
  1120. }
  1121.       } else {
  1122. LOGE("Error on getpwuid() errno: %d", errno);
  1123.       }
  1124.     } else {
  1125.       LOGD("Error on getsockopt() errno: %d", errno);
  1126.     }
  1127.     if ( !is_phone_socket ) {
  1128.       LOGE("RILD must accept socket from %s", PHONE_PROCESS);
  1129.         
  1130.       close(s_fdCommand);
  1131.       s_fdCommand = -1;
  1132.       onCommandsSocketClosed();
  1133.       /* start listening for new connections again */
  1134.       rilEventAddWakeup(&s_listen_event);
  1135.       return;
  1136.     }
  1137.     ret = fcntl(s_fdCommand, F_SETFL, O_NONBLOCK);
  1138.     if (ret < 0) {
  1139.         LOGE ("Error setting O_NONBLOCK errno:%d", errno);
  1140.     }
  1141.     LOGI("libril: new connection");
  1142.     p_rs = record_stream_new(s_fdCommand, MAX_COMMAND_BYTES);
  1143.     ril_event_set (&s_commands_event, s_fdCommand, 1, 
  1144.         processCommandsCallback, p_rs);
  1145.     rilEventAddWakeup (&s_commands_event);
  1146.     onNewCommandConnect();
  1147. }
  1148. static void freeDebugCallbackArgs(int number, char **args) {
  1149.     for (int i = 0; i < number; i++) {
  1150.         if (args[i] != NULL) {
  1151.             free(args[i]);
  1152.         }
  1153.     }
  1154.     free(args);
  1155. }
  1156. static void debugCallback (int fd, short flags, void *param)
  1157. {
  1158.     int acceptFD, option;
  1159.     struct sockaddr_un peeraddr;
  1160.     socklen_t socklen = sizeof (peeraddr);
  1161.     int data;
  1162.     unsigned int qxdm_data[6];
  1163.     const char *deactData[1] = {"1"};
  1164.     char *actData[1];
  1165.     RIL_Dial dialData;
  1166.     int hangupData[1] = {1};
  1167.     int number;
  1168.     char **args;
  1169.     acceptFD = accept (fd,  (sockaddr *) &peeraddr, &socklen);
  1170.     if (acceptFD < 0) {
  1171.         LOGE ("error accepting on debug port: %dn", errno);
  1172.         return;
  1173.     }
  1174.     if (recv(acceptFD, &number, sizeof(int), 0) != sizeof(int)) {
  1175.         LOGE ("error reading on socket: number of Args: n");
  1176.         return;
  1177.     }
  1178.     args = (char **) malloc(sizeof(char*) * number);
  1179.     for (int i = 0; i < number; i++) {
  1180.         int len;
  1181.         if (recv(acceptFD, &len, sizeof(int), 0) != sizeof(int)) {
  1182.             LOGE ("error reading on socket: Len of Args: n");
  1183.             freeDebugCallbackArgs(i, args);
  1184.             return;
  1185.         }
  1186.         // +1 for null-term
  1187.         args[i] = (char *) malloc((sizeof(char) * len) + 1);
  1188.         if (recv(acceptFD, args[i], sizeof(char) * len, 0) 
  1189.             != sizeof(char) * len) {
  1190.             LOGE ("error reading on socket: Args[%d] n", i);
  1191.             freeDebugCallbackArgs(i, args);
  1192.             return;
  1193.         }
  1194.         char * buf = args[i];
  1195.         buf[len] = 0;
  1196.     }
  1197.     switch (atoi(args[0])) {
  1198.         case 0:
  1199.             LOGI ("Connection on debug port: issuing reset.");
  1200.             issueLocalRequest(RIL_REQUEST_RESET_RADIO, NULL, 0);
  1201.             break;
  1202.         case 1:
  1203.             LOGI ("Connection on debug port: issuing radio power off.");
  1204.             data = 0;
  1205.             issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int));
  1206.             // Close the socket
  1207.             close(s_fdCommand);
  1208.             s_fdCommand = -1;
  1209.             break;
  1210.         case 2:
  1211.             LOGI ("Debug port: issuing unsolicited network change.");
  1212.             RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED,
  1213.                                       NULL, 0);
  1214.             break;
  1215.         case 3:
  1216.             LOGI ("Debug port: QXDM log enable.");
  1217.             qxdm_data[0] = 65536;
  1218.             qxdm_data[1] = 16;
  1219.             qxdm_data[2] = 1;
  1220.             qxdm_data[3] = 32;
  1221.             qxdm_data[4] = 0;
  1222.             qxdm_data[4] = 8;
  1223.             issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data, 
  1224.                               6 * sizeof(int));
  1225.             break;
  1226.         case 4:
  1227.             LOGI ("Debug port: QXDM log disable.");
  1228.             qxdm_data[0] = 65536;
  1229.             qxdm_data[1] = 16;
  1230.             qxdm_data[2] = 0;
  1231.             qxdm_data[3] = 32;
  1232.             qxdm_data[4] = 0;
  1233.             qxdm_data[4] = 8;
  1234.             issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
  1235.                               6 * sizeof(int));
  1236.             break;
  1237.         case 5:
  1238.             LOGI("Debug port: Radio On");
  1239.             data = 1;
  1240.             issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int));
  1241.             sleep(2);
  1242.             // Set network selection automatic.
  1243.             issueLocalRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, NULL, 0);
  1244.             break;
  1245.         case 6:
  1246.             LOGI("Debug port: Setup PDP, Apn :%sn", args[1]);
  1247.             actData[0] = args[1];
  1248.             issueLocalRequest(RIL_REQUEST_SETUP_DEFAULT_PDP, &actData, 
  1249.                               sizeof(actData));
  1250.             break;
  1251.         case 7:
  1252.             LOGI("Debug port: Deactivate PDP");
  1253.             issueLocalRequest(RIL_REQUEST_DEACTIVATE_DEFAULT_PDP, &deactData, 
  1254.                               sizeof(deactData));
  1255.             break;
  1256.         case 8:
  1257.             LOGI("Debug port: Dial Call");
  1258.             dialData.clir = 0;
  1259.             dialData.address = args[1];
  1260.             issueLocalRequest(RIL_REQUEST_DIAL, &dialData, sizeof(dialData));
  1261.             break;
  1262.         case 9:
  1263.             LOGI("Debug port: Answer Call");
  1264.             issueLocalRequest(RIL_REQUEST_ANSWER, NULL, 0);
  1265.             break;
  1266.         case 10:
  1267.             LOGI("Debug port: End Call");
  1268.             issueLocalRequest(RIL_REQUEST_HANGUP, &hangupData, 
  1269.                               sizeof(hangupData));
  1270.             break;
  1271.         default:
  1272.             LOGE ("Invalid request");
  1273.             break;
  1274.     }
  1275.     freeDebugCallbackArgs(number, args);
  1276.     close(acceptFD);
  1277. }
  1278. static void userTimerCallback (int fd, short flags, void *param)
  1279. {
  1280.     UserCallbackInfo *p_info;
  1281.     p_info = (UserCallbackInfo *)param;
  1282.     p_info->p_callback(p_info->userParam);
  1283.     // FIXME generalize this...there should be a cancel mechanism
  1284.     if (s_last_wake_timeout_info != NULL && s_last_wake_timeout_info == p_info) {
  1285.         s_last_wake_timeout_info = NULL;
  1286.     }
  1287.     free(p_info);
  1288. }
  1289. static void *
  1290. eventLoop(void *param)
  1291. {
  1292.     int ret;
  1293.     int filedes[2];
  1294.     ril_event_init();
  1295.     pthread_mutex_lock(&s_startupMutex);
  1296.     s_started = 1;
  1297.     pthread_cond_broadcast(&s_startupCond);
  1298.     pthread_mutex_unlock(&s_startupMutex);
  1299.     ret = pipe(filedes);
  1300.     if (ret < 0) {
  1301.         LOGE("Error in pipe() errno:%d", errno);
  1302.         return NULL;
  1303.     }
  1304.     s_fdWakeupRead = filedes[0];
  1305.     s_fdWakeupWrite = filedes[1];
  1306.     fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
  1307.     ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
  1308.                 processWakeupCallback, NULL);
  1309.     rilEventAddWakeup (&s_wakeupfd_event);
  1310.     // Only returns on error
  1311.     ril_event_loop();
  1312.     LOGE ("error in event_loop_base errno:%d", errno);
  1313.     return NULL;
  1314. }
  1315. extern "C" void 
  1316. RIL_startEventLoop(void)
  1317. {
  1318.     int ret;
  1319.     pthread_attr_t attr;
  1320.     
  1321.     /* spin up eventLoop thread and wait for it to get started */
  1322.     s_started = 0;
  1323.     pthread_mutex_lock(&s_startupMutex);
  1324.     pthread_attr_init (&attr);
  1325.     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);    
  1326.     ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
  1327.     while (s_started == 0) {
  1328.         pthread_cond_wait(&s_startupCond, &s_startupMutex);
  1329.     }
  1330.     pthread_mutex_unlock(&s_startupMutex);
  1331.     if (ret < 0) {
  1332.         LOGE("Failed to create dispatch thread errno:%d", errno);
  1333.         return;
  1334.     }
  1335. }
  1336. // Used for testing purpose only.
  1337. extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) {
  1338.     memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
  1339. }
  1340. extern "C" void 
  1341. RIL_register (const RIL_RadioFunctions *callbacks)
  1342. {
  1343.     int ret;
  1344.     int flags;
  1345.     if (callbacks == NULL 
  1346.         || ! (callbacks->version == RIL_VERSION || callbacks->version == 1)
  1347.     ) {
  1348.         LOGE(
  1349.             "RIL_register: RIL_RadioFunctions * null or invalid version"
  1350.             " (expected %d)", RIL_VERSION);
  1351.         return;
  1352.     }
  1353.     if (s_registerCalled > 0) {
  1354.         LOGE("RIL_register has been called more than once. "
  1355.                 "Subsequent call ignored");
  1356.         return;
  1357.     }
  1358.     memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
  1359.     s_registerCalled = 1;
  1360.     // Little self-check
  1361.     for (int i = 0; i < (int)NUM_ELEMS(s_commands) ; i++) {
  1362.         assert(i == s_commands[i].requestNumber);
  1363.     }
  1364.     for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses) ; i++) {
  1365.         assert(i + RIL_UNSOL_RESPONSE_BASE 
  1366.                 == s_unsolResponses[i].requestNumber);
  1367.     }
  1368.     // New rild impl calls RIL_startEventLoop() first
  1369.     // old standalone impl wants it here.
  1370.     if (s_started == 0) {
  1371.         RIL_startEventLoop();
  1372.     }
  1373.     // start listen socket
  1374. #if 0
  1375.     ret = socket_local_server (SOCKET_NAME_RIL, 
  1376.             ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
  1377.     if (ret < 0) {
  1378.         LOGE("Unable to bind socket errno:%d", errno);
  1379.         exit (-1);
  1380.     }
  1381.     s_fdListen = ret;
  1382. #else
  1383.     s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);
  1384.     if (s_fdListen < 0) {
  1385.         LOGE("Failed to get socket '" SOCKET_NAME_RIL "'");
  1386.         exit(-1);
  1387.     }
  1388.     ret = listen(s_fdListen, 4);
  1389.     if (ret < 0) {
  1390.         LOGE("Failed to listen on control socket '%d': %s",
  1391.              s_fdListen, strerror(errno));
  1392.         exit(-1);
  1393.     }
  1394. #endif
  1395.     /* note: non-persistent so we can accept only one connection at a time */
  1396.     ril_event_set (&s_listen_event, s_fdListen, false, 
  1397.                 listenCallback, NULL);
  1398.     rilEventAddWakeup (&s_listen_event);
  1399. #if 1
  1400.     // start debug interface socket
  1401.     s_fdDebug = android_get_control_socket(SOCKET_NAME_RIL_DEBUG);
  1402.     if (s_fdDebug < 0) {
  1403.         LOGE("Failed to get socket '" SOCKET_NAME_RIL_DEBUG "' errno:%d", errno);
  1404.         exit(-1);
  1405.     }
  1406.     ret = listen(s_fdDebug, 4);
  1407.     if (ret < 0) {
  1408.         LOGE("Failed to listen on ril debug socket '%d': %s",
  1409.              s_fdDebug, strerror(errno));
  1410.         exit(-1);
  1411.     }
  1412.     ril_event_set (&s_debug_event, s_fdDebug, true,
  1413.                 debugCallback, NULL);
  1414.     rilEventAddWakeup (&s_debug_event);
  1415. #endif
  1416. }
  1417. static int
  1418. checkAndDequeueRequestInfo(struct RequestInfo *pRI)
  1419. {
  1420.     int ret = 0;
  1421.     
  1422.     if (pRI == NULL) {
  1423.         return 0;
  1424.     }
  1425.     pthread_mutex_lock(&s_pendingRequestsMutex);
  1426.     for(RequestInfo **ppCur = &s_pendingRequests 
  1427.         ; *ppCur != NULL 
  1428.         ; ppCur = &((*ppCur)->p_next)
  1429.     ) {
  1430.         if (pRI == *ppCur) {
  1431.             ret = 1;
  1432.             *ppCur = (*ppCur)->p_next;
  1433.             break;
  1434.         }
  1435.     }
  1436.     pthread_mutex_unlock(&s_pendingRequestsMutex);
  1437.     return ret;
  1438. }
  1439. extern "C" void
  1440. RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen)
  1441. {
  1442.     RequestInfo *pRI;
  1443.     int ret;
  1444.     size_t errorOffset;
  1445.     pRI = (RequestInfo *)t;
  1446.     if (!checkAndDequeueRequestInfo(pRI)) {
  1447.         LOGE ("RIL_onRequestComplete: invalid RIL_Token");
  1448.         return;
  1449.     }
  1450.     if (pRI->local > 0) {
  1451.         // Locally issued command...void only!
  1452.         // response does not go back up the command socket
  1453.         LOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
  1454.         goto done;
  1455.     }
  1456.     appendPrintBuf("[%04d]< %s",
  1457.         pRI->token, requestToString(pRI->pCI->requestNumber));
  1458.     if (pRI->cancelled == 0) {
  1459.         Parcel p;
  1460.         p.writeInt32 (RESPONSE_SOLICITED);
  1461.         p.writeInt32 (pRI->token);
  1462.         errorOffset = p.dataPosition();
  1463.         p.writeInt32 (e);
  1464.         if (e == RIL_E_SUCCESS) {
  1465.             /* process response on success */
  1466.             ret = pRI->pCI->responseFunction(p, response, responselen);
  1467.             /* if an error occurred, rewind and mark it */
  1468.             if (ret != 0) {
  1469.                 p.setDataPosition(errorOffset);
  1470.                 p.writeInt32 (ret);
  1471.             }
  1472.         } else {
  1473.             appendPrintBuf("%s returns %s", printBuf, failCauseToString(e));
  1474.         }
  1475.         if (s_fdCommand < 0) {
  1476.             LOGD ("RIL onRequestComplete: Command channel closed");
  1477.         }
  1478.         sendResponse(p);
  1479.     }
  1480. done:
  1481.     free(pRI);
  1482. }
  1483. static void
  1484. grabFullWakeLock()
  1485. {
  1486.     int fd;
  1487.     fd = open (ANDROID_FULL_WAKE_LOCK_PATH, O_WRONLY);
  1488.     if (fd < 0) {
  1489.         LOGW ("Cannot open " ANDROID_FULL_WAKE_LOCK_PATH);
  1490.         return;
  1491.     }
  1492.     write (fd, ANDROID_WAKE_LOCK_NAME, strlen(ANDROID_WAKE_LOCK_NAME));
  1493.     close (fd);
  1494. }
  1495. static void
  1496. grabPartialWakeLock()
  1497. {
  1498.     int fd;
  1499.     fd = open (ANDROID_PARTIAL_WAKE_LOCK_PATH, O_WRONLY);
  1500.     if (fd < 0) {
  1501.         LOGW ("Cannot open " ANDROID_PARTIAL_WAKE_LOCK_PATH);
  1502.         return;
  1503.     }
  1504.     write (fd, ANDROID_WAKE_LOCK_NAME, strlen(ANDROID_WAKE_LOCK_NAME));
  1505.     close (fd);
  1506. }
  1507. static void
  1508. releaseWakeLock()
  1509. {
  1510.     int fd;
  1511.     fd = open (ANDROID_WAKE_UNLOCK_PATH, O_WRONLY);
  1512.     if (fd < 0) {
  1513.         LOGW ("Cannot open " ANDROID_WAKE_UNLOCK_PATH);
  1514.         return;
  1515.     }
  1516.     write (fd, ANDROID_WAKE_LOCK_NAME, strlen(ANDROID_WAKE_LOCK_NAME));
  1517.     close (fd);
  1518. }
  1519. /**
  1520.  * Timer callback to put us back to sleep before the default timeout
  1521.  */
  1522. static void
  1523. wakeTimeoutCallback (void *param)
  1524. {
  1525.     // We're using "param != NULL" as a cancellation mechanism
  1526.     if (param == NULL) {
  1527.         //LOGD("wakeTimeout: releasing wake lock");
  1528.         releaseWakeLock();
  1529.     } else {
  1530.         //LOGD("wakeTimeout: releasing wake lock CANCELLED");
  1531.     }
  1532. }
  1533. extern "C"
  1534. void RIL_onUnsolicitedResponse(int unsolResponse, void *data, 
  1535.                                 size_t datalen)
  1536. {
  1537.     int unsolResponseIndex;
  1538.     int ret;
  1539.     if (s_registerCalled == 0) {
  1540.         // Ignore RIL_onUnsolicitedResponse before RIL_register
  1541.         LOGW("RIL_onUnsolicitedResponse called before RIL_register");
  1542.         return;
  1543.     }
  1544.         
  1545.     unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
  1546.     if (unsolResponseIndex < 0 
  1547.         || unsolResponseIndex >= (int32_t)NUM_ELEMS(s_unsolResponses)) {
  1548.         LOGE("unsupported unsolicited response code %d", unsolResponse);
  1549.         return;
  1550.     }
  1551.     appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
  1552.     
  1553.     Parcel p;
  1554.     p.writeInt32 (RESPONSE_UNSOLICITED);
  1555.     p.writeInt32 (unsolResponse);
  1556.     ret = s_unsolResponses[unsolResponseIndex]
  1557.                 .responseFunction(p, data, datalen);
  1558.     // some things get more payload
  1559.     switch(unsolResponse) {
  1560.         case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
  1561.             p.writeInt32(s_callbacks.onStateRequest());
  1562.             appendPrintBuf("%s {%s}", printBuf,
  1563.                 radioStateToString(s_callbacks.onStateRequest()));
  1564.         break;
  1565.         case RIL_UNSOL_NITZ_TIME_RECEIVED: 
  1566.             int64_t timeReceived = elapsedRealtime();
  1567.             // Store the time this was received in case it is delayed
  1568.             p.writeInt64(timeReceived);
  1569.         break;
  1570.     }    
  1571.     
  1572.     if (ret != 0) {
  1573.         // Problem with the response. Don't continue;        
  1574.         return;
  1575.     }
  1576.     ret = sendResponse(p);
  1577.     if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
  1578.         // Unfortunately, NITZ time is not poll/update like everything
  1579.         // else in the system. So, if the upstream client isn't connected,
  1580.         // keep a copy of the last NITZ response (with receive time noted
  1581.         // above) around so we can deliver it when it is connected
  1582.         
  1583.         if (s_lastNITZTimeData != NULL) {
  1584.             free (s_lastNITZTimeData);
  1585.             s_lastNITZTimeData = NULL;
  1586.         }
  1587.         s_lastNITZTimeData = malloc(p.dataSize());
  1588.         s_lastNITZTimeDataSize = p.dataSize();
  1589.         memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
  1590.     }
  1591.     bool shouldScheduleTimeout = false;
  1592.     
  1593.     switch (s_unsolResponses[unsolResponseIndex].wakeType) {
  1594.         case WAKE_PARTIAL:
  1595.             grabPartialWakeLock();
  1596.             shouldScheduleTimeout = true;
  1597.         break;
  1598.         case WAKE_FULL:
  1599.             grabFullWakeLock();
  1600.             shouldScheduleTimeout = true;
  1601.         break;
  1602.         case DONT_WAKE:
  1603.         default:
  1604.             break;
  1605.     }
  1606.     // For now, we automatically go back to sleep after TIMEVAL_WAKE_TIMEOUT
  1607.     // FIXME The java code should handshake here to release wake lock
  1608.     if (shouldScheduleTimeout) {
  1609.         // Cancel the previous request
  1610.         if (s_last_wake_timeout_info != NULL) {
  1611.             s_last_wake_timeout_info->userParam = (void *)1;
  1612.         }
  1613.         
  1614.         s_last_wake_timeout_info 
  1615.             = internalRequestTimedCallback(wakeTimeoutCallback, NULL, 
  1616.                                             &TIMEVAL_WAKE_TIMEOUT);
  1617.     }
  1618. }
  1619. /** FIXME generalize this if you track UserCAllbackInfo, clear it  
  1620.     when the callback occurs 
  1621. */
  1622. static UserCallbackInfo *
  1623. internalRequestTimedCallback (RIL_TimedCallback callback, void *param, 
  1624.                                 const struct timeval *relativeTime)
  1625. {
  1626.     struct timeval myRelativeTime;
  1627.     UserCallbackInfo *p_info;
  1628.     p_info = (UserCallbackInfo *) malloc (sizeof(UserCallbackInfo));
  1629.     p_info->p_callback = callback; 
  1630.     p_info->userParam = param;
  1631.     if (relativeTime == NULL) {
  1632.         /* treat null parameter as a 0 relative time */
  1633.         memset (&myRelativeTime, 0, sizeof(myRelativeTime));
  1634.     } else {
  1635.         /* FIXME I think event_add's tv param is really const anyway */
  1636.         memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime));
  1637.     }
  1638.     ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info);
  1639.     ril_timer_add(&(p_info->event), &myRelativeTime);
  1640.     triggerEvLoop();
  1641.     return p_info;
  1642. }
  1643. extern "C" void
  1644. RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, 
  1645.                                 const struct timeval *relativeTime)
  1646. {
  1647.     internalRequestTimedCallback (callback, param, relativeTime);
  1648. }
  1649. const char *
  1650. failCauseToString(RIL_Errno e)
  1651. {
  1652.     switch(e) {
  1653.         case RIL_E_SUCCESS: return "E_SUCCESS";
  1654.         case RIL_E_RADIO_NOT_AVAILABLE: return "E_RAIDO_NOT_AVAILABLE";
  1655.         case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE";
  1656.         case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT";
  1657.         case RIL_E_SIM_PIN2: return "E_SIM_PIN2";
  1658.         case RIL_E_SIM_PUK2: return "E_SIM_PUK2";
  1659.         case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED";
  1660.         case RIL_E_CANCELLED: return "E_CANCELLED";
  1661.         case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL";
  1662.         case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW";
  1663.         case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY";
  1664.         default: return "<unknown error>";
  1665.     }
  1666. }
  1667. const char *
  1668. radioStateToString(RIL_RadioState s)
  1669. {
  1670.     switch(s) {
  1671.         case RADIO_STATE_OFF: return "RADIO_OFF";
  1672.         case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE";
  1673.         case RADIO_STATE_SIM_NOT_READY: return "RADIO_SIM_NOT_READY";
  1674.         case RADIO_STATE_SIM_LOCKED_OR_ABSENT: return "RADIO_SIM_LOCKED_OR_ABSENT";
  1675.         case RADIO_STATE_SIM_READY: return "RADIO_SIM_READY";
  1676.         default: return "<unknown state>";
  1677.     }
  1678. }
  1679. const char *
  1680. callStateToString(RIL_CallState s)
  1681. {
  1682.     switch(s) {
  1683.         case RIL_CALL_ACTIVE : return "ACTIVE";
  1684.         case RIL_CALL_HOLDING: return "HOLDING";
  1685.         case RIL_CALL_DIALING: return "DIALING";
  1686.         case RIL_CALL_ALERTING: return "ALERTING";
  1687.         case RIL_CALL_INCOMING: return "INCOMING";
  1688.         case RIL_CALL_WAITING: return "WAITING";
  1689.         default: return "<unknown state>";
  1690.     }
  1691. }
  1692. const char *
  1693. requestToString(int request) 
  1694. {
  1695. /*
  1696.  cat libs/telephony/ril_commands.h 
  1697.  | egrep "^ *{RIL_" 
  1698.  | sed -re 's/{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_1: return "1";/'
  1699.  cat libs/telephony/ril_unsol_commands.h 
  1700.  | egrep "^ *{RIL_" 
  1701.  | sed -re 's/{RIL_([^,]+),([^}]+).+/case RIL_1: return "1";/'
  1702. */
  1703.     switch(request) {
  1704.         case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
  1705.         case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
  1706.         case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
  1707.         case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
  1708.         case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
  1709.         case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
  1710.         case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
  1711.         case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
  1712.         case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
  1713.         case RIL_REQUEST_DIAL: return "DIAL";
  1714.         case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
  1715.         case RIL_REQUEST_HANGUP: return "HANGUP";
  1716.         case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
  1717.         case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
  1718.         case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
  1719.         case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
  1720.         case RIL_REQUEST_UDUB: return "UDUB";
  1721.         case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
  1722.         case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
  1723.         case RIL_REQUEST_REGISTRATION_STATE: return "REGISTRATION_STATE";
  1724.         case RIL_REQUEST_GPRS_REGISTRATION_STATE: return "GPRS_REGISTRATION_STATE";
  1725.         case RIL_REQUEST_OPERATOR: return "OPERATOR";
  1726.         case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
  1727.         case RIL_REQUEST_DTMF: return "DTMF";
  1728.         case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
  1729.         case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
  1730.         case RIL_REQUEST_SETUP_DEFAULT_PDP: return "SETUP_DEFAULT_PDP";
  1731.         case RIL_REQUEST_SIM_IO: return "SIM_IO";
  1732.         case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
  1733.         case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
  1734.         case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
  1735.         case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
  1736.         case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
  1737.         case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
  1738.         case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
  1739.         case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
  1740.         case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
  1741.         case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
  1742.         case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
  1743.         case RIL_REQUEST_ANSWER: return "ANSWER";
  1744.         case RIL_REQUEST_DEACTIVATE_DEFAULT_PDP: return "DEACTIVATE_DEFAULT_PDP";
  1745.         case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
  1746.         case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
  1747.         case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
  1748.         case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
  1749.         case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
  1750.         case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
  1751.         case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
  1752.         case RIL_REQUEST_DTMF_START: return "DTMF_START";
  1753.         case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
  1754.         case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
  1755.         case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
  1756.         case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE";
  1757.         case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE";
  1758.         case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS";
  1759.         case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
  1760.         case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
  1761.         case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
  1762.         case RIL_REQUEST_LAST_PDP_FAIL_CAUSE: return "LAST_PDP_FAIL_CAUSE";
  1763.         case RIL_REQUEST_PDP_CONTEXT_LIST: return "PDP_CONTEXT_LIST";
  1764.         case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
  1765.         case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
  1766.         case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
  1767.     case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
  1768.     case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
  1769.         case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE";
  1770.         case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE";
  1771.         case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND";
  1772.         case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE";
  1773.         case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
  1774.         case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
  1775.         case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER";
  1776.         case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES";
  1777.         case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
  1778.         case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
  1779.         case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_NETWORK_STATE_CHANGED";
  1780.         case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
  1781.         case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
  1782.         case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
  1783.         case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
  1784.         case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
  1785.         case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
  1786.         case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
  1787.         case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
  1788.         case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
  1789.         case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
  1790.         case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
  1791.         case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FUL";
  1792.         case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
  1793.         case RIL_UNSOL_PDP_CONTEXT_LIST_CHANGED: return "UNSOL_PDP_CONTEXT_LIST_CHANGED";
  1794.         case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
  1795.         default: return "<unknown request>";
  1796.     }
  1797. }
  1798. } /* namespace android */