blob: e56e6f41d3c9e1cda287be6e321caac36dbb2c53 [file] [log] [blame]
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001/* //device/libs/telephony/ril.cpp
2**
3** Copyright 2006, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#define LOG_TAG "RILC"
19
20#include <hardware_legacy/power.h>
21
22#include <telephony/ril.h>
23#include <telephony/ril_cdma_sms.h>
24#include <cutils/sockets.h>
25#include <cutils/jstring.h>
Andrew Jiangca4a9a02014-01-18 18:04:08 -050026#include <telephony/record_stream.h>
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020027#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>
XpLoDWilDba5c6a32013-07-27 21:12:19 +020034#include <sys/limits.h>
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020035#include <pwd.h>
36
37#include <stdio.h>
38#include <stdlib.h>
39#include <stdarg.h>
40#include <string.h>
41#include <unistd.h>
42#include <fcntl.h>
43#include <time.h>
44#include <errno.h>
45#include <assert.h>
46#include <ctype.h>
47#include <alloca.h>
48#include <sys/un.h>
49#include <assert.h>
50#include <netinet/in.h>
51#include <cutils/properties.h>
52
53#include <ril_event.h>
54
55namespace android {
56
57#define PHONE_PROCESS "radio"
58
59#define SOCKET_NAME_RIL "rild"
Howard Sue32dbfd2015-01-07 15:55:57 +080060#define SOCKET2_NAME_RIL "rild2"
61#define SOCKET3_NAME_RIL "rild3"
62#define SOCKET4_NAME_RIL "rild4"
63
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020064#define SOCKET_NAME_RIL_DEBUG "rild-debug"
65
66#define ANDROID_WAKE_LOCK_NAME "radio-interface"
67
68
69#define PROPERTY_RIL_IMPL "gsm.version.ril-impl"
70
71// match with constant in RIL.java
72#define MAX_COMMAND_BYTES (8 * 1024)
73
74// Basically: memset buffers that the client library
75// shouldn't be using anymore in an attempt to find
76// memory usage issues sooner.
77#define MEMSET_FREED 1
78
79#define NUM_ELEMS(a) (sizeof (a) / sizeof (a)[0])
80
81#define MIN(a,b) ((a)<(b) ? (a) : (b))
82
83/* Constants for response types */
84#define RESPONSE_SOLICITED 0
85#define RESPONSE_UNSOLICITED 1
86
87/* Negative values for private RIL errno's */
88#define RIL_ERRNO_INVALID_RESPONSE -1
89
90// request, response, and unsolicited msg print macro
91#define PRINTBUF_SIZE 8096
92
93// Enable RILC log
94#define RILC_LOG 0
95
96#if RILC_LOG
97 #define startRequest sprintf(printBuf, "(")
98 #define closeRequest sprintf(printBuf, "%s)", printBuf)
99 #define printRequest(token, req) \
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200100 RLOGD("[%04d]> %s %s", token, requestToString(req), printBuf)
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200101
102 #define startResponse sprintf(printBuf, "%s {", printBuf)
103 #define closeResponse sprintf(printBuf, "%s}", printBuf)
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200104 #define printResponse RLOGD("%s", printBuf)
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200105
106 #define clearPrintBuf printBuf[0] = 0
107 #define removeLastChar printBuf[strlen(printBuf)-1] = 0
108 #define appendPrintBuf(x...) sprintf(printBuf, x)
109#else
110 #define startRequest
111 #define closeRequest
112 #define printRequest(token, req)
113 #define startResponse
114 #define closeResponse
115 #define printResponse
116 #define clearPrintBuf
117 #define removeLastChar
118 #define appendPrintBuf(x...)
119#endif
120
121enum WakeType {DONT_WAKE, WAKE_PARTIAL};
122
123typedef struct {
124 int requestNumber;
125 void (*dispatchFunction) (Parcel &p, struct RequestInfo *pRI);
126 int(*responseFunction) (Parcel &p, void *response, size_t responselen);
127} CommandInfo;
128
129typedef struct {
130 int requestNumber;
131 int (*responseFunction) (Parcel &p, void *response, size_t responselen);
132 WakeType wakeType;
133} UnsolResponseInfo;
134
135typedef struct RequestInfo {
136 int32_t token; //this is not RIL_Token
137 CommandInfo *pCI;
138 struct RequestInfo *p_next;
139 char cancelled;
140 char local; // responses to local commands do not go back to command process
Howard Sue32dbfd2015-01-07 15:55:57 +0800141 RIL_SOCKET_ID socket_id;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200142} RequestInfo;
143
144typedef struct UserCallbackInfo {
145 RIL_TimedCallback p_callback;
146 void *userParam;
147 struct ril_event event;
148 struct UserCallbackInfo *p_next;
149} UserCallbackInfo;
150
Howard Sue32dbfd2015-01-07 15:55:57 +0800151typedef struct SocketListenParam {
152 RIL_SOCKET_ID socket_id;
153 int fdListen;
154 int fdCommand;
155 char* processName;
156 struct ril_event* commands_event;
157 struct ril_event* listen_event;
158 void (*processCommandsCallback)(int fd, short flags, void *param);
159 RecordStream *p_rs;
160} SocketListenParam;
161
162extern "C" const char * requestToString(int request);
163extern "C" const char * failCauseToString(RIL_Errno);
164extern "C" const char * callStateToString(RIL_CallState);
165extern "C" const char * radioStateToString(RIL_RadioState);
166extern "C" const char * rilSocketIdToString(RIL_SOCKET_ID socket_id);
167
168extern "C"
169char rild[MAX_SOCKET_NAME_LENGTH] = SOCKET_NAME_RIL;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200170
Howard Subd82ef12015-04-12 10:25:05 +0200171#define RIL_VENDOR_COMMANDS_OFFSET 10000
172
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200173/*******************************************************************/
174
175RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL};
176static int s_registerCalled = 0;
177
178static pthread_t s_tid_dispatch;
179static pthread_t s_tid_reader;
180static int s_started = 0;
181
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200182static int s_fdDebug = -1;
Howard Sue32dbfd2015-01-07 15:55:57 +0800183static int s_fdDebug_socket2 = -1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200184
185static int s_fdWakeupRead;
186static int s_fdWakeupWrite;
187
188static struct ril_event s_commands_event;
189static struct ril_event s_wakeupfd_event;
190static struct ril_event s_listen_event;
Howard Sue32dbfd2015-01-07 15:55:57 +0800191static SocketListenParam s_ril_param_socket;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200192
193static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER;
194static pthread_mutex_t s_writeMutex = PTHREAD_MUTEX_INITIALIZER;
Howard Sue32dbfd2015-01-07 15:55:57 +0800195static RequestInfo *s_pendingRequests = NULL;
196
197#if (SIM_COUNT >= 2)
198static struct ril_event s_commands_event_socket2;
199static struct ril_event s_listen_event_socket2;
200static SocketListenParam s_ril_param_socket2;
201
202static pthread_mutex_t s_pendingRequestsMutex_socket2 = PTHREAD_MUTEX_INITIALIZER;
203static pthread_mutex_t s_writeMutex_socket2 = PTHREAD_MUTEX_INITIALIZER;
204static RequestInfo *s_pendingRequests_socket2 = NULL;
205#endif
206
207#if (SIM_COUNT >= 3)
208static struct ril_event s_commands_event_socket3;
209static struct ril_event s_listen_event_socket3;
210static SocketListenParam s_ril_param_socket3;
211
212static pthread_mutex_t s_pendingRequestsMutex_socket3 = PTHREAD_MUTEX_INITIALIZER;
213static pthread_mutex_t s_writeMutex_socket3 = PTHREAD_MUTEX_INITIALIZER;
214static RequestInfo *s_pendingRequests_socket3 = NULL;
215#endif
216
217#if (SIM_COUNT >= 4)
218static struct ril_event s_commands_event_socket4;
219static struct ril_event s_listen_event_socket4;
220static SocketListenParam s_ril_param_socket4;
221
222static pthread_mutex_t s_pendingRequestsMutex_socket4 = PTHREAD_MUTEX_INITIALIZER;
223static pthread_mutex_t s_writeMutex_socket4 = PTHREAD_MUTEX_INITIALIZER;
224static RequestInfo *s_pendingRequests_socket4 = NULL;
225#endif
226
227static struct ril_event s_wake_timeout_event;
228static struct ril_event s_debug_event;
229
Howard Subd82ef12015-04-12 10:25:05 +0200230
Howard Sue32dbfd2015-01-07 15:55:57 +0800231static const struct timeval TIMEVAL_WAKE_TIMEOUT = {1,0};
232
Howard Subd82ef12015-04-12 10:25:05 +0200233
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200234static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
235static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER;
236
237static pthread_mutex_t s_dispatchMutex = PTHREAD_MUTEX_INITIALIZER;
238static pthread_cond_t s_dispatchCond = PTHREAD_COND_INITIALIZER;
239
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200240static RequestInfo *s_toDispatchHead = NULL;
241static RequestInfo *s_toDispatchTail = NULL;
242
243static UserCallbackInfo *s_last_wake_timeout_info = NULL;
244
245static void *s_lastNITZTimeData = NULL;
246static size_t s_lastNITZTimeDataSize;
247
248#if RILC_LOG
249 static char printBuf[PRINTBUF_SIZE];
250#endif
251
252/*******************************************************************/
Howard Sue32dbfd2015-01-07 15:55:57 +0800253static int sendResponse (Parcel &p, RIL_SOCKET_ID socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200254
255static void dispatchVoid (Parcel& p, RequestInfo *pRI);
256static void dispatchString (Parcel& p, RequestInfo *pRI);
257static void dispatchStrings (Parcel& p, RequestInfo *pRI);
258static void dispatchInts (Parcel& p, RequestInfo *pRI);
259static void dispatchDial (Parcel& p, RequestInfo *pRI);
260static void dispatchSIM_IO (Parcel& p, RequestInfo *pRI);
Howard Sue32dbfd2015-01-07 15:55:57 +0800261static void dispatchSIM_APDU (Parcel& p, RequestInfo *pRI);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200262static void dispatchCallForward(Parcel& p, RequestInfo *pRI);
263static void dispatchRaw(Parcel& p, RequestInfo *pRI);
264static void dispatchSmsWrite (Parcel &p, RequestInfo *pRI);
265static void dispatchDataCall (Parcel& p, RequestInfo *pRI);
266static void dispatchVoiceRadioTech (Parcel& p, RequestInfo *pRI);
Andrew Jiangca4a9a02014-01-18 18:04:08 -0500267static void dispatchSetInitialAttachApn (Parcel& p, RequestInfo *pRI);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200268static void dispatchCdmaSubscriptionSource (Parcel& p, RequestInfo *pRI);
269
270static void dispatchCdmaSms(Parcel &p, RequestInfo *pRI);
Andrew Jiangca4a9a02014-01-18 18:04:08 -0500271static void dispatchImsSms(Parcel &p, RequestInfo *pRI);
272static void dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef);
273static void dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200274static void dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI);
275static void dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI);
276static void dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI);
277static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI);
Howard Sue32dbfd2015-01-07 15:55:57 +0800278static void dispatchNVReadItem(Parcel &p, RequestInfo *pRI);
279static void dispatchNVWriteItem(Parcel &p, RequestInfo *pRI);
280static void dispatchUiccSubscripton(Parcel &p, RequestInfo *pRI);
281static void dispatchSimAuthentication(Parcel &p, RequestInfo *pRI);
282static void dispatchDataProfile(Parcel &p, RequestInfo *pRI);
Howard Subd82ef12015-04-12 10:25:05 +0200283static void dispatchRadioCapability(Parcel &p, RequestInfo *pRI);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200284static int responseInts(Parcel &p, void *response, size_t responselen);
Daniel Hillenbrandd0b84162015-04-12 11:53:23 +0200285static int responseIntsGetPreferredNetworkType(Parcel &p, void *response, size_t responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200286static int responseStrings(Parcel &p, void *response, size_t responselen);
Utkarsh Guptaf7a63e52015-05-10 16:53:37 +0530287static int responseStringsNetworks(Parcel &p, void *response, size_t responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200288static int responseStrings(Parcel &p, void *response, size_t responselen, bool network_search);
289static int responseString(Parcel &p, void *response, size_t responselen);
290static int responseVoid(Parcel &p, void *response, size_t responselen);
291static int responseCallList(Parcel &p, void *response, size_t responselen);
292static int responseSMS(Parcel &p, void *response, size_t responselen);
293static int responseSIM_IO(Parcel &p, void *response, size_t responselen);
294static int responseCallForwards(Parcel &p, void *response, size_t responselen);
295static int responseDataCallList(Parcel &p, void *response, size_t responselen);
296static int responseSetupDataCall(Parcel &p, void *response, size_t responselen);
297static int responseRaw(Parcel &p, void *response, size_t responselen);
298static int responseSsn(Parcel &p, void *response, size_t responselen);
299static int responseSimStatus(Parcel &p, void *response, size_t responselen);
300static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen);
301static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen);
302static int responseCdmaSms(Parcel &p, void *response, size_t responselen);
303static int responseCellList(Parcel &p, void *response, size_t responselen);
304static int responseCdmaInformationRecords(Parcel &p,void *response, size_t responselen);
305static int responseRilSignalStrength(Parcel &p,void *response, size_t responselen);
306static int responseCallRing(Parcel &p, void *response, size_t responselen);
307static int responseCdmaSignalInfoRecord(Parcel &p,void *response, size_t responselen);
308static int responseCdmaCallWaiting(Parcel &p,void *response, size_t responselen);
309static int responseSimRefresh(Parcel &p, void *response, size_t responselen);
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200310static int responseCellInfoList(Parcel &p, void *response, size_t responselen);
Howard Sue32dbfd2015-01-07 15:55:57 +0800311static int responseHardwareConfig(Parcel &p, void *response, size_t responselen);
312static int responseDcRtInfo(Parcel &p, void *response, size_t responselen);
Howard Subd82ef12015-04-12 10:25:05 +0200313static int responseRadioCapability(Parcel &p, void *response, size_t responselen);
314static int responseSSData(Parcel &p, void *response, size_t responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200315
316static int decodeVoiceRadioTechnology (RIL_RadioState radioState);
317static int decodeCdmaSubscriptionSource (RIL_RadioState radioState);
Howard Subd82ef12015-04-12 10:25:05 +0200318static RIL_RadioState processRadioState(RIL_RadioState newRadioState);
319
320static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200321
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200322#ifdef RIL_SHLIB
Howard Sue32dbfd2015-01-07 15:55:57 +0800323#if defined(ANDROID_MULTI_SIM)
Andreas Schneider47b2d962015-04-13 22:54:49 +0200324extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
Howard Sue32dbfd2015-01-07 15:55:57 +0800325 size_t datalen, RIL_SOCKET_ID socket_id);
326#else
Andreas Schneider47b2d962015-04-13 22:54:49 +0200327extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200328 size_t datalen);
329#endif
Howard Sue32dbfd2015-01-07 15:55:57 +0800330#endif
331
332#if defined(ANDROID_MULTI_SIM)
333#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c), (d))
334#define CALL_ONREQUEST(a, b, c, d, e) s_callbacks.onRequest((a), (b), (c), (d), (e))
335#define CALL_ONSTATEREQUEST(a) s_callbacks.onStateRequest(a)
336#else
337#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c))
338#define CALL_ONREQUEST(a, b, c, d, e) s_callbacks.onRequest((a), (b), (c), (d))
339#define CALL_ONSTATEREQUEST(a) s_callbacks.onStateRequest()
340#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200341
342static UserCallbackInfo * internalRequestTimedCallback
343 (RIL_TimedCallback callback, void *param,
344 const struct timeval *relativeTime);
345
346/** Index == requestNumber */
347static CommandInfo s_commands[] = {
348#include "ril_commands.h"
349};
350
Howard Subd82ef12015-04-12 10:25:05 +0200351static CommandInfo s_commands_v[] = {
352#include "ril_commands_vendor.h"
353};
354
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200355static UnsolResponseInfo s_unsolResponses[] = {
356#include "ril_unsol_commands.h"
357};
358
Howard Subd82ef12015-04-12 10:25:05 +0200359static UnsolResponseInfo s_unsolResponses_v[] = {
360#include "ril_unsol_commands_vendor.h"
361};
362
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200363/* For older RILs that do not support new commands RIL_REQUEST_VOICE_RADIO_TECH and
364 RIL_UNSOL_VOICE_RADIO_TECH_CHANGED messages, decode the voice radio tech from
365 radio state message and store it. Every time there is a change in Radio State
366 check to see if voice radio tech changes and notify telephony
367 */
368int voiceRadioTech = -1;
369
370/* For older RILs that do not support new commands RIL_REQUEST_GET_CDMA_SUBSCRIPTION_SOURCE
371 and RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED messages, decode the subscription
372 source from radio state and store it. Every time there is a change in Radio State
373 check to see if subscription source changed and notify telephony
374 */
375int cdmaSubscriptionSource = -1;
376
377/* For older RILs that do not send RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, decode the
378 SIM/RUIM state from radio state and store it. Every time there is a change in Radio State,
379 check to see if SIM/RUIM status changed and notify telephony
380 */
381int simRuimStatus = -1;
382
Howard Sue32dbfd2015-01-07 15:55:57 +0800383static char * RIL_getRilSocketName() {
384 return rild;
385}
386
387extern "C"
388void RIL_setRilSocketName(char * s) {
389 strncpy(rild, s, MAX_SOCKET_NAME_LENGTH);
390}
391
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200392static char *
393strdupReadString(Parcel &p) {
394 size_t stringlen;
395 const char16_t *s16;
396
397 s16 = p.readString16Inplace(&stringlen);
398
399 return strndup16to8(s16, stringlen);
400}
401
Howard Subd82ef12015-04-12 10:25:05 +0200402static status_t
403readStringFromParcelInplace(Parcel &p, char *str, size_t maxLen) {
404 size_t s16Len;
405 const char16_t *s16;
406
407 s16 = p.readString16Inplace(&s16Len);
408 if (s16 == NULL) {
409 return NO_MEMORY;
410 }
411 size_t strLen = strnlen16to8(s16, s16Len);
412 if ((strLen + 1) > maxLen) {
413 return NO_MEMORY;
414 }
415 if (strncpy16to8(str, s16, strLen) == NULL) {
416 return NO_MEMORY;
417 } else {
418 return NO_ERROR;
419 }
420}
421
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200422static void writeStringToParcel(Parcel &p, const char *s) {
423 char16_t *s16;
424 size_t s16_len;
425 s16 = strdup8to16(s, &s16_len);
426 p.writeString16(s16, s16_len);
427 free(s16);
428}
429
430
431static void
432memsetString (char *s) {
433 if (s != NULL) {
434 memset (s, 0, strlen(s));
435 }
436}
437
438void nullParcelReleaseFunction (const uint8_t* data, size_t dataSize,
439 const size_t* objects, size_t objectsSize,
440 void* cookie) {
441 // do nothing -- the data reference lives longer than the Parcel object
442}
443
444/**
445 * To be called from dispatch thread
446 * Issue a single local request, ensuring that the response
447 * is not sent back up to the command process
448 */
449static void
Howard Sue32dbfd2015-01-07 15:55:57 +0800450issueLocalRequest(int request, void *data, int len, RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200451 RequestInfo *pRI;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200452 int ret;
Howard Sue32dbfd2015-01-07 15:55:57 +0800453 /* Hook for current context */
454 /* pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
455 pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
456 /* pendingRequestsHook refer to &s_pendingRequests */
457 RequestInfo** pendingRequestsHook = &s_pendingRequests;
458
459#if (SIM_COUNT == 2)
460 if (socket_id == RIL_SOCKET_2) {
461 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
462 pendingRequestsHook = &s_pendingRequests_socket2;
463 }
464#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200465
466 pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
467
468 pRI->local = 1;
469 pRI->token = 0xffffffff; // token is not used in this context
470
Howard Subd82ef12015-04-12 10:25:05 +0200471 /* Check vendor commands */
472 if (request > RIL_VENDOR_COMMANDS_OFFSET) {
473 pRI->pCI = &(s_commands_v[request - RIL_VENDOR_COMMANDS_OFFSET]);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200474 } else {
475 pRI->pCI = &(s_commands[request]);
476 }
Howard Sue32dbfd2015-01-07 15:55:57 +0800477 pRI->socket_id = socket_id;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200478
Howard Sue32dbfd2015-01-07 15:55:57 +0800479 ret = pthread_mutex_lock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200480 assert (ret == 0);
481
Howard Sue32dbfd2015-01-07 15:55:57 +0800482 pRI->p_next = *pendingRequestsHook;
483 *pendingRequestsHook = pRI;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200484
Howard Sue32dbfd2015-01-07 15:55:57 +0800485 ret = pthread_mutex_unlock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200486 assert (ret == 0);
487
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200488 RLOGD("C[locl]> %s", requestToString(request));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200489
Howard Sue32dbfd2015-01-07 15:55:57 +0800490 CALL_ONREQUEST(request, data, len, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200491}
492
Howard Subd82ef12015-04-12 10:25:05 +0200493
494
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200495static int
Howard Sue32dbfd2015-01-07 15:55:57 +0800496processCommandBuffer(void *buffer, size_t buflen, RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200497 Parcel p;
498 status_t status;
499 int32_t request;
500 int32_t token;
501 RequestInfo *pRI;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200502 int ret;
Howard Sue32dbfd2015-01-07 15:55:57 +0800503 /* Hook for current context */
504 /* pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
505 pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
506 /* pendingRequestsHook refer to &s_pendingRequests */
507 RequestInfo** pendingRequestsHook = &s_pendingRequests;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200508
509 p.setData((uint8_t *) buffer, buflen);
510
511 // status checked at end
512 status = p.readInt32(&request);
513 status = p.readInt32 (&token);
514
Howard Sue32dbfd2015-01-07 15:55:57 +0800515#if (SIM_COUNT >= 2)
516 if (socket_id == RIL_SOCKET_2) {
517 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
518 pendingRequestsHook = &s_pendingRequests_socket2;
519 }
520#if (SIM_COUNT >= 3)
521 else if (socket_id == RIL_SOCKET_3) {
522 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
523 pendingRequestsHook = &s_pendingRequests_socket3;
524 }
525#endif
526#if (SIM_COUNT >= 4)
527 else if (socket_id == RIL_SOCKET_4) {
528 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
529 pendingRequestsHook = &s_pendingRequests_socket4;
530 }
531#endif
532#endif
533
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200534 if (status != NO_ERROR) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200535 RLOGE("invalid request block");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200536 return 0;
537 }
538
Howard Subd82ef12015-04-12 10:25:05 +0200539 CommandInfo *pCI = NULL;
540 if (request > RIL_VENDOR_COMMANDS_OFFSET) {
541 int index = request - RIL_VENDOR_COMMANDS_OFFSET;
542 RLOGD("processCommandBuffer: samsung request=%d, index=%d",
543 request, index);
544 if (index < (int32_t)NUM_ELEMS(s_commands_v))
545 pCI = &(s_commands_v[index]);
546 } else {
547 if (request < (int32_t)NUM_ELEMS(s_commands))
548 pCI = &(s_commands[request]);
549 }
Howard Sue32dbfd2015-01-07 15:55:57 +0800550
Howard Subd82ef12015-04-12 10:25:05 +0200551 if (pCI == NULL) {
552 Parcel pErr;
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200553 RLOGE("unsupported request code %d token %d", request, token);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200554 // FIXME this should perhaps return a response
Howard Sue32dbfd2015-01-07 15:55:57 +0800555 pErr.writeInt32 (RESPONSE_SOLICITED);
556 pErr.writeInt32 (token);
557 pErr.writeInt32 (RIL_E_GENERIC_FAILURE);
558
559 sendResponse(pErr, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200560 return 0;
561 }
562
563 pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
564
565 pRI->token = token;
Howard Subd82ef12015-04-12 10:25:05 +0200566 pRI->pCI = pCI;
Howard Sue32dbfd2015-01-07 15:55:57 +0800567 pRI->socket_id = socket_id;
568
569 ret = pthread_mutex_lock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200570 assert (ret == 0);
571
Howard Sue32dbfd2015-01-07 15:55:57 +0800572 pRI->p_next = *pendingRequestsHook;
573 *pendingRequestsHook = pRI;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200574
Howard Sue32dbfd2015-01-07 15:55:57 +0800575 ret = pthread_mutex_unlock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200576 assert (ret == 0);
577
578/* sLastDispatchedToken = token; */
579
580 pRI->pCI->dispatchFunction(p, pRI);
581
582 return 0;
583}
584
585static void
586invalidCommandBlock (RequestInfo *pRI) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200587 RLOGE("invalid command block for token %d request %s",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200588 pRI->token, requestToString(pRI->pCI->requestNumber));
589}
590
591/** Callee expects NULL */
592static void
593dispatchVoid (Parcel& p, RequestInfo *pRI) {
594 clearPrintBuf;
595 printRequest(pRI->token, pRI->pCI->requestNumber);
Howard Sue32dbfd2015-01-07 15:55:57 +0800596 CALL_ONREQUEST(pRI->pCI->requestNumber, NULL, 0, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200597}
598
599/** Callee expects const char * */
600static void
601dispatchString (Parcel& p, RequestInfo *pRI) {
602 status_t status;
603 size_t datalen;
604 size_t stringlen;
605 char *string8 = NULL;
606
607 string8 = strdupReadString(p);
608
609 startRequest;
610 appendPrintBuf("%s%s", printBuf, string8);
611 closeRequest;
612 printRequest(pRI->token, pRI->pCI->requestNumber);
613
Howard Sue32dbfd2015-01-07 15:55:57 +0800614 CALL_ONREQUEST(pRI->pCI->requestNumber, string8,
615 sizeof(char *), pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200616
617#ifdef MEMSET_FREED
618 memsetString(string8);
619#endif
620
621 free(string8);
622 return;
623invalid:
624 invalidCommandBlock(pRI);
625 return;
626}
627
628/** Callee expects const char ** */
629static void
630dispatchStrings (Parcel &p, RequestInfo *pRI) {
631 int32_t countStrings;
632 status_t status;
633 size_t datalen;
634 char **pStrings;
635
636 status = p.readInt32 (&countStrings);
637
638 if (status != NO_ERROR) {
639 goto invalid;
640 }
641
642 startRequest;
643 if (countStrings == 0) {
644 // just some non-null pointer
645 pStrings = (char **)alloca(sizeof(char *));
646 datalen = 0;
647 } else if (((int)countStrings) == -1) {
648 pStrings = NULL;
649 datalen = 0;
650 } else {
651 datalen = sizeof(char *) * countStrings;
652
653 pStrings = (char **)alloca(datalen);
654
655 for (int i = 0 ; i < countStrings ; i++) {
656 pStrings[i] = strdupReadString(p);
657 appendPrintBuf("%s%s,", printBuf, pStrings[i]);
658 }
659 }
660 removeLastChar;
661 closeRequest;
662 printRequest(pRI->token, pRI->pCI->requestNumber);
663
Howard Sue32dbfd2015-01-07 15:55:57 +0800664 CALL_ONREQUEST(pRI->pCI->requestNumber, pStrings, datalen, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200665
666 if (pStrings != NULL) {
667 for (int i = 0 ; i < countStrings ; i++) {
668#ifdef MEMSET_FREED
669 memsetString (pStrings[i]);
670#endif
671 free(pStrings[i]);
672 }
673
674#ifdef MEMSET_FREED
675 memset(pStrings, 0, datalen);
676#endif
677 }
678
679 return;
680invalid:
681 invalidCommandBlock(pRI);
682 return;
683}
684
685/** Callee expects const int * */
686static void
687dispatchInts (Parcel &p, RequestInfo *pRI) {
688 int32_t count;
689 status_t status;
690 size_t datalen;
691 int *pInts;
692
693 status = p.readInt32 (&count);
694
695 if (status != NO_ERROR || count == 0) {
696 goto invalid;
697 }
698
699 datalen = sizeof(int) * count;
700 pInts = (int *)alloca(datalen);
701
702 startRequest;
703 for (int i = 0 ; i < count ; i++) {
704 int32_t t;
705
706 status = p.readInt32(&t);
707 pInts[i] = (int)t;
708 appendPrintBuf("%s%d,", printBuf, t);
709
710 if (status != NO_ERROR) {
711 goto invalid;
712 }
713 }
714 removeLastChar;
715 closeRequest;
716 printRequest(pRI->token, pRI->pCI->requestNumber);
717
Howard Sue32dbfd2015-01-07 15:55:57 +0800718 CALL_ONREQUEST(pRI->pCI->requestNumber, const_cast<int *>(pInts),
719 datalen, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200720
721#ifdef MEMSET_FREED
722 memset(pInts, 0, datalen);
723#endif
724
725 return;
726invalid:
727 invalidCommandBlock(pRI);
728 return;
729}
730
731
732/**
733 * Callee expects const RIL_SMS_WriteArgs *
734 * Payload is:
735 * int32_t status
736 * String pdu
737 */
738static void
739dispatchSmsWrite (Parcel &p, RequestInfo *pRI) {
740 RIL_SMS_WriteArgs args;
741 int32_t t;
742 status_t status;
743
744 memset (&args, 0, sizeof(args));
745
746 status = p.readInt32(&t);
747 args.status = (int)t;
748
749 args.pdu = strdupReadString(p);
750
751 if (status != NO_ERROR || args.pdu == NULL) {
752 goto invalid;
753 }
754
755 args.smsc = strdupReadString(p);
756
757 startRequest;
758 appendPrintBuf("%s%d,%s,smsc=%s", printBuf, args.status,
759 (char*)args.pdu, (char*)args.smsc);
760 closeRequest;
761 printRequest(pRI->token, pRI->pCI->requestNumber);
762
Howard Sue32dbfd2015-01-07 15:55:57 +0800763 CALL_ONREQUEST(pRI->pCI->requestNumber, &args, sizeof(args), pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200764
765#ifdef MEMSET_FREED
766 memsetString (args.pdu);
767#endif
768
769 free (args.pdu);
770
771#ifdef MEMSET_FREED
772 memset(&args, 0, sizeof(args));
773#endif
774
775 return;
776invalid:
777 invalidCommandBlock(pRI);
778 return;
779}
780
781/**
782 * Callee expects const RIL_Dial *
783 * Payload is:
784 * String address
785 * int32_t clir
786 */
787static void
788dispatchDial (Parcel &p, RequestInfo *pRI) {
789 RIL_Dial dial;
790 RIL_UUS_Info uusInfo;
791 int32_t sizeOfDial;
792 int32_t t;
793 int32_t uusPresent;
Andreas Schneider29472682015-01-01 19:00:04 +0100794#ifdef MODEM_TYPE_XMM7260
795 char *csv;
796#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200797 status_t status;
798
799 memset (&dial, 0, sizeof(dial));
800
801 dial.address = strdupReadString(p);
802
803 status = p.readInt32(&t);
804 dial.clir = (int)t;
805
806 if (status != NO_ERROR || dial.address == NULL) {
807 goto invalid;
808 }
809
Andreas Schneider29472682015-01-01 19:00:04 +0100810#ifdef MODEM_TYPE_XMM7260
811 /* CallDetails.call_type */
812 status = p.readInt32(&t);
813 if (status != NO_ERROR) {
814 goto invalid;
815 }
816 /* CallDetails.call_domain */
817 p.readInt32(&t);
818 if (status != NO_ERROR) {
819 goto invalid;
820 }
821 /* CallDetails.getCsvFromExtra */
822 csv = strdupReadString(p);
823 if (csv == NULL) {
824 goto invalid;
825 }
826 free(csv);
827#endif
828
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200829 if (s_callbacks.version < 3) { // Remove when partners upgrade to version 3
830 uusPresent = 0;
831 sizeOfDial = sizeof(dial) - sizeof(RIL_UUS_Info *);
832 } else {
833 status = p.readInt32(&uusPresent);
834
835 if (status != NO_ERROR) {
836 goto invalid;
837 }
838
839 if (uusPresent == 0) {
Andreas Schneidereef440e2015-04-07 19:01:54 +0200840#if defined(MODEM_TYPE_XMM6262) || defined(MODEM_TYPE_XMM7260)
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200841 dial.uusInfo = NULL;
Andreas Schneiderf68609b2015-04-07 19:01:34 +0200842#elif defined(MODEM_TYPE_XMM6260)
Howard Sue32dbfd2015-01-07 15:55:57 +0800843 /* Samsung hack */
844 memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
845 uusInfo.uusType = (RIL_UUS_Type) 0;
846 uusInfo.uusDcs = (RIL_UUS_DCS) 0;
847 uusInfo.uusData = NULL;
848 uusInfo.uusLength = 0;
849 dial.uusInfo = &uusInfo;
850#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200851 } else {
852 int32_t len;
853
854 memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
855
856 status = p.readInt32(&t);
857 uusInfo.uusType = (RIL_UUS_Type) t;
858
859 status = p.readInt32(&t);
860 uusInfo.uusDcs = (RIL_UUS_DCS) t;
861
862 status = p.readInt32(&len);
863 if (status != NO_ERROR) {
864 goto invalid;
865 }
866
867 // The java code writes -1 for null arrays
868 if (((int) len) == -1) {
869 uusInfo.uusData = NULL;
870 len = 0;
871 } else {
872 uusInfo.uusData = (char*) p.readInplace(len);
873 }
874
875 uusInfo.uusLength = len;
876 dial.uusInfo = &uusInfo;
877 }
878 sizeOfDial = sizeof(dial);
879 }
880
881 startRequest;
882 appendPrintBuf("%snum=%s,clir=%d", printBuf, dial.address, dial.clir);
883 if (uusPresent) {
884 appendPrintBuf("%s,uusType=%d,uusDcs=%d,uusLen=%d", printBuf,
885 dial.uusInfo->uusType, dial.uusInfo->uusDcs,
886 dial.uusInfo->uusLength);
887 }
888 closeRequest;
889 printRequest(pRI->token, pRI->pCI->requestNumber);
890
Howard Sue32dbfd2015-01-07 15:55:57 +0800891 CALL_ONREQUEST(pRI->pCI->requestNumber, &dial, sizeOfDial, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200892
893#ifdef MEMSET_FREED
894 memsetString (dial.address);
895#endif
896
897 free (dial.address);
898
899#ifdef MEMSET_FREED
900 memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
901 memset(&dial, 0, sizeof(dial));
902#endif
903
904 return;
905invalid:
906 invalidCommandBlock(pRI);
907 return;
908}
909
910/**
911 * Callee expects const RIL_SIM_IO *
912 * Payload is:
913 * int32_t command
914 * int32_t fileid
915 * String path
916 * int32_t p1, p2, p3
917 * String data
918 * String pin2
919 * String aidPtr
920 */
921static void
922dispatchSIM_IO (Parcel &p, RequestInfo *pRI) {
923 union RIL_SIM_IO {
924 RIL_SIM_IO_v6 v6;
925 RIL_SIM_IO_v5 v5;
926 } simIO;
927
928 int32_t t;
929 int size;
930 status_t status;
931
932 memset (&simIO, 0, sizeof(simIO));
933
934 // note we only check status at the end
935
936 status = p.readInt32(&t);
937 simIO.v6.command = (int)t;
938
939 status = p.readInt32(&t);
940 simIO.v6.fileid = (int)t;
941
942 simIO.v6.path = strdupReadString(p);
943
944 status = p.readInt32(&t);
945 simIO.v6.p1 = (int)t;
946
947 status = p.readInt32(&t);
948 simIO.v6.p2 = (int)t;
949
950 status = p.readInt32(&t);
951 simIO.v6.p3 = (int)t;
952
953 simIO.v6.data = strdupReadString(p);
954 simIO.v6.pin2 = strdupReadString(p);
955 simIO.v6.aidPtr = strdupReadString(p);
956
957 startRequest;
958 appendPrintBuf("%scmd=0x%X,efid=0x%X,path=%s,%d,%d,%d,%s,pin2=%s,aid=%s", printBuf,
959 simIO.v6.command, simIO.v6.fileid, (char*)simIO.v6.path,
960 simIO.v6.p1, simIO.v6.p2, simIO.v6.p3,
961 (char*)simIO.v6.data, (char*)simIO.v6.pin2, simIO.v6.aidPtr);
962 closeRequest;
963 printRequest(pRI->token, pRI->pCI->requestNumber);
964
965 if (status != NO_ERROR) {
966 goto invalid;
967 }
968
969 size = (s_callbacks.version < 6) ? sizeof(simIO.v5) : sizeof(simIO.v6);
Howard Sue32dbfd2015-01-07 15:55:57 +0800970 CALL_ONREQUEST(pRI->pCI->requestNumber, &simIO, size, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200971
972#ifdef MEMSET_FREED
973 memsetString (simIO.v6.path);
974 memsetString (simIO.v6.data);
975 memsetString (simIO.v6.pin2);
976 memsetString (simIO.v6.aidPtr);
977#endif
978
979 free (simIO.v6.path);
980 free (simIO.v6.data);
981 free (simIO.v6.pin2);
982 free (simIO.v6.aidPtr);
983
984#ifdef MEMSET_FREED
985 memset(&simIO, 0, sizeof(simIO));
986#endif
987
988 return;
989invalid:
990 invalidCommandBlock(pRI);
991 return;
992}
993
994/**
Howard Sue32dbfd2015-01-07 15:55:57 +0800995 * Callee expects const RIL_SIM_APDU *
996 * Payload is:
997 * int32_t sessionid
998 * int32_t cla
999 * int32_t instruction
1000 * int32_t p1, p2, p3
1001 * String data
1002 */
1003static void
1004dispatchSIM_APDU (Parcel &p, RequestInfo *pRI) {
1005 int32_t t;
1006 status_t status;
1007 RIL_SIM_APDU apdu;
1008
1009 memset (&apdu, 0, sizeof(RIL_SIM_APDU));
1010
1011 // Note we only check status at the end. Any single failure leads to
1012 // subsequent reads filing.
1013 status = p.readInt32(&t);
1014 apdu.sessionid = (int)t;
1015
1016 status = p.readInt32(&t);
1017 apdu.cla = (int)t;
1018
1019 status = p.readInt32(&t);
1020 apdu.instruction = (int)t;
1021
1022 status = p.readInt32(&t);
1023 apdu.p1 = (int)t;
1024
1025 status = p.readInt32(&t);
1026 apdu.p2 = (int)t;
1027
1028 status = p.readInt32(&t);
1029 apdu.p3 = (int)t;
1030
1031 apdu.data = strdupReadString(p);
1032
1033 startRequest;
1034 appendPrintBuf("%ssessionid=%d,cla=%d,ins=%d,p1=%d,p2=%d,p3=%d,data=%s",
1035 printBuf, apdu.sessionid, apdu.cla, apdu.instruction, apdu.p1, apdu.p2,
1036 apdu.p3, (char*)apdu.data);
1037 closeRequest;
1038 printRequest(pRI->token, pRI->pCI->requestNumber);
1039
1040 if (status != NO_ERROR) {
1041 goto invalid;
1042 }
1043
1044 CALL_ONREQUEST(pRI->pCI->requestNumber, &apdu, sizeof(RIL_SIM_APDU), pRI, pRI->socket_id);
1045
1046#ifdef MEMSET_FREED
1047 memsetString(apdu.data);
1048#endif
1049 free(apdu.data);
1050
1051#ifdef MEMSET_FREED
1052 memset(&apdu, 0, sizeof(RIL_SIM_APDU));
1053#endif
1054
1055 return;
1056invalid:
1057 invalidCommandBlock(pRI);
1058 return;
1059}
1060
Howard Subd82ef12015-04-12 10:25:05 +02001061
Howard Sue32dbfd2015-01-07 15:55:57 +08001062/**
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001063 * Callee expects const RIL_CallForwardInfo *
1064 * Payload is:
1065 * int32_t status/action
1066 * int32_t reason
1067 * int32_t serviceCode
1068 * int32_t toa
1069 * String number (0 length -> null)
1070 * int32_t timeSeconds
1071 */
1072static void
1073dispatchCallForward(Parcel &p, RequestInfo *pRI) {
1074 RIL_CallForwardInfo cff;
1075 int32_t t;
1076 status_t status;
1077
1078 memset (&cff, 0, sizeof(cff));
1079
1080 // note we only check status at the end
1081
1082 status = p.readInt32(&t);
1083 cff.status = (int)t;
1084
1085 status = p.readInt32(&t);
1086 cff.reason = (int)t;
1087
1088 status = p.readInt32(&t);
1089 cff.serviceClass = (int)t;
1090
1091 status = p.readInt32(&t);
1092 cff.toa = (int)t;
1093
1094 cff.number = strdupReadString(p);
1095
1096 status = p.readInt32(&t);
1097 cff.timeSeconds = (int)t;
1098
1099 if (status != NO_ERROR) {
1100 goto invalid;
1101 }
1102
1103 // special case: number 0-length fields is null
1104
1105 if (cff.number != NULL && strlen (cff.number) == 0) {
1106 cff.number = NULL;
1107 }
1108
1109 startRequest;
1110 appendPrintBuf("%sstat=%d,reason=%d,serv=%d,toa=%d,%s,tout=%d", printBuf,
1111 cff.status, cff.reason, cff.serviceClass, cff.toa,
1112 (char*)cff.number, cff.timeSeconds);
1113 closeRequest;
1114 printRequest(pRI->token, pRI->pCI->requestNumber);
1115
Howard Sue32dbfd2015-01-07 15:55:57 +08001116 CALL_ONREQUEST(pRI->pCI->requestNumber, &cff, sizeof(cff), pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001117
1118#ifdef MEMSET_FREED
1119 memsetString(cff.number);
1120#endif
1121
1122 free (cff.number);
1123
1124#ifdef MEMSET_FREED
1125 memset(&cff, 0, sizeof(cff));
1126#endif
1127
1128 return;
1129invalid:
1130 invalidCommandBlock(pRI);
1131 return;
1132}
1133
1134
1135static void
1136dispatchRaw(Parcel &p, RequestInfo *pRI) {
1137 int32_t len;
1138 status_t status;
1139 const void *data;
1140
1141 status = p.readInt32(&len);
1142
1143 if (status != NO_ERROR) {
1144 goto invalid;
1145 }
1146
1147 // The java code writes -1 for null arrays
1148 if (((int)len) == -1) {
1149 data = NULL;
1150 len = 0;
1151 }
1152
1153 data = p.readInplace(len);
1154
1155 startRequest;
1156 appendPrintBuf("%sraw_size=%d", printBuf, len);
1157 closeRequest;
1158 printRequest(pRI->token, pRI->pCI->requestNumber);
1159
Howard Sue32dbfd2015-01-07 15:55:57 +08001160 CALL_ONREQUEST(pRI->pCI->requestNumber, const_cast<void *>(data), len, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001161
1162 return;
1163invalid:
1164 invalidCommandBlock(pRI);
1165 return;
1166}
1167
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001168static status_t
1169constructCdmaSms(Parcel &p, RequestInfo *pRI, RIL_CDMA_SMS_Message& rcsm) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001170 int32_t t;
1171 uint8_t ut;
1172 status_t status;
1173 int32_t digitCount;
1174 int digitLimit;
1175
1176 memset(&rcsm, 0, sizeof(rcsm));
1177
1178 status = p.readInt32(&t);
1179 rcsm.uTeleserviceID = (int) t;
1180
1181 status = p.read(&ut,sizeof(ut));
1182 rcsm.bIsServicePresent = (uint8_t) ut;
1183
1184 status = p.readInt32(&t);
1185 rcsm.uServicecategory = (int) t;
1186
1187 status = p.readInt32(&t);
1188 rcsm.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
1189
1190 status = p.readInt32(&t);
1191 rcsm.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
1192
1193 status = p.readInt32(&t);
1194 rcsm.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
1195
1196 status = p.readInt32(&t);
1197 rcsm.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
1198
1199 status = p.read(&ut,sizeof(ut));
1200 rcsm.sAddress.number_of_digits= (uint8_t) ut;
1201
1202 digitLimit= MIN((rcsm.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
1203 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1204 status = p.read(&ut,sizeof(ut));
1205 rcsm.sAddress.digits[digitCount] = (uint8_t) ut;
1206 }
1207
1208 status = p.readInt32(&t);
1209 rcsm.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
1210
1211 status = p.read(&ut,sizeof(ut));
1212 rcsm.sSubAddress.odd = (uint8_t) ut;
1213
1214 status = p.read(&ut,sizeof(ut));
1215 rcsm.sSubAddress.number_of_digits = (uint8_t) ut;
1216
1217 digitLimit= MIN((rcsm.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
1218 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1219 status = p.read(&ut,sizeof(ut));
1220 rcsm.sSubAddress.digits[digitCount] = (uint8_t) ut;
1221 }
1222
1223 status = p.readInt32(&t);
1224 rcsm.uBearerDataLen = (int) t;
1225
1226 digitLimit= MIN((rcsm.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
1227 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1228 status = p.read(&ut, sizeof(ut));
1229 rcsm.aBearerData[digitCount] = (uint8_t) ut;
1230 }
1231
1232 if (status != NO_ERROR) {
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001233 return status;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001234 }
1235
1236 startRequest;
1237 appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
1238 sAddress.digit_mode=%d, sAddress.Number_mode=%d, sAddress.number_type=%d, ",
1239 printBuf, rcsm.uTeleserviceID,rcsm.bIsServicePresent,rcsm.uServicecategory,
1240 rcsm.sAddress.digit_mode, rcsm.sAddress.number_mode,rcsm.sAddress.number_type);
1241 closeRequest;
1242
1243 printRequest(pRI->token, pRI->pCI->requestNumber);
1244
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001245 return status;
1246}
1247
1248static void
1249dispatchCdmaSms(Parcel &p, RequestInfo *pRI) {
1250 RIL_CDMA_SMS_Message rcsm;
1251
1252 ALOGD("dispatchCdmaSms");
1253 if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) {
1254 goto invalid;
1255 }
1256
Howard Sue32dbfd2015-01-07 15:55:57 +08001257 CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm),pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001258
1259#ifdef MEMSET_FREED
1260 memset(&rcsm, 0, sizeof(rcsm));
1261#endif
1262
1263 return;
1264
1265invalid:
1266 invalidCommandBlock(pRI);
1267 return;
1268}
1269
1270static void
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001271dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) {
1272 RIL_IMS_SMS_Message rism;
1273 RIL_CDMA_SMS_Message rcsm;
1274
1275 ALOGD("dispatchImsCdmaSms: retry=%d, messageRef=%d", retry, messageRef);
1276
1277 if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) {
1278 goto invalid;
1279 }
1280 memset(&rism, 0, sizeof(rism));
1281 rism.tech = RADIO_TECH_3GPP2;
1282 rism.retry = retry;
1283 rism.messageRef = messageRef;
1284 rism.message.cdmaMessage = &rcsm;
1285
Howard Sue32dbfd2015-01-07 15:55:57 +08001286 CALL_ONREQUEST(pRI->pCI->requestNumber, &rism,
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001287 sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t)
Howard Sue32dbfd2015-01-07 15:55:57 +08001288 +sizeof(rcsm),pRI, pRI->socket_id);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001289
1290#ifdef MEMSET_FREED
1291 memset(&rcsm, 0, sizeof(rcsm));
1292 memset(&rism, 0, sizeof(rism));
1293#endif
1294
1295 return;
1296
1297invalid:
1298 invalidCommandBlock(pRI);
1299 return;
1300}
1301
1302static void
1303dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) {
1304 RIL_IMS_SMS_Message rism;
1305 int32_t countStrings;
1306 status_t status;
1307 size_t datalen;
1308 char **pStrings;
1309 ALOGD("dispatchImsGsmSms: retry=%d, messageRef=%d", retry, messageRef);
1310
1311 status = p.readInt32 (&countStrings);
1312
1313 if (status != NO_ERROR) {
1314 goto invalid;
1315 }
1316
1317 memset(&rism, 0, sizeof(rism));
1318 rism.tech = RADIO_TECH_3GPP;
1319 rism.retry = retry;
1320 rism.messageRef = messageRef;
1321
1322 startRequest;
Howard Sue32dbfd2015-01-07 15:55:57 +08001323 appendPrintBuf("%stech=%d, retry=%d, messageRef=%d, ", printBuf,
1324 (int)rism.tech, (int)rism.retry, rism.messageRef);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001325 if (countStrings == 0) {
1326 // just some non-null pointer
1327 pStrings = (char **)alloca(sizeof(char *));
1328 datalen = 0;
1329 } else if (((int)countStrings) == -1) {
1330 pStrings = NULL;
1331 datalen = 0;
1332 } else {
1333 datalen = sizeof(char *) * countStrings;
1334
1335 pStrings = (char **)alloca(datalen);
1336
1337 for (int i = 0 ; i < countStrings ; i++) {
1338 pStrings[i] = strdupReadString(p);
1339 appendPrintBuf("%s%s,", printBuf, pStrings[i]);
1340 }
1341 }
1342 removeLastChar;
1343 closeRequest;
1344 printRequest(pRI->token, pRI->pCI->requestNumber);
1345
1346 rism.message.gsmMessage = pStrings;
Howard Sue32dbfd2015-01-07 15:55:57 +08001347 CALL_ONREQUEST(pRI->pCI->requestNumber, &rism,
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001348 sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t)
Howard Sue32dbfd2015-01-07 15:55:57 +08001349 +datalen, pRI, pRI->socket_id);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001350
1351 if (pStrings != NULL) {
1352 for (int i = 0 ; i < countStrings ; i++) {
1353#ifdef MEMSET_FREED
1354 memsetString (pStrings[i]);
1355#endif
1356 free(pStrings[i]);
1357 }
1358
1359#ifdef MEMSET_FREED
1360 memset(pStrings, 0, datalen);
1361#endif
1362 }
1363
1364#ifdef MEMSET_FREED
1365 memset(&rism, 0, sizeof(rism));
1366#endif
1367 return;
1368invalid:
1369 ALOGE("dispatchImsGsmSms invalid block");
1370 invalidCommandBlock(pRI);
1371 return;
1372}
1373
1374static void
1375dispatchImsSms(Parcel &p, RequestInfo *pRI) {
1376 int32_t t;
1377 status_t status = p.readInt32(&t);
1378 RIL_RadioTechnologyFamily format;
1379 uint8_t retry;
1380 int32_t messageRef;
1381
1382 ALOGD("dispatchImsSms");
1383 if (status != NO_ERROR) {
1384 goto invalid;
1385 }
1386 format = (RIL_RadioTechnologyFamily) t;
1387
1388 // read retry field
1389 status = p.read(&retry,sizeof(retry));
1390 if (status != NO_ERROR) {
1391 goto invalid;
1392 }
1393 // read messageRef field
1394 status = p.read(&messageRef,sizeof(messageRef));
1395 if (status != NO_ERROR) {
1396 goto invalid;
1397 }
1398
1399 if (RADIO_TECH_3GPP == format) {
1400 dispatchImsGsmSms(p, pRI, retry, messageRef);
1401 } else if (RADIO_TECH_3GPP2 == format) {
1402 dispatchImsCdmaSms(p, pRI, retry, messageRef);
1403 } else {
1404 ALOGE("requestImsSendSMS invalid format value =%d", format);
1405 }
1406
1407 return;
1408
1409invalid:
1410 invalidCommandBlock(pRI);
1411 return;
1412}
1413
1414static void
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001415dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI) {
1416 RIL_CDMA_SMS_Ack rcsa;
1417 int32_t t;
1418 status_t status;
1419 int32_t digitCount;
1420
1421 memset(&rcsa, 0, sizeof(rcsa));
1422
1423 status = p.readInt32(&t);
1424 rcsa.uErrorClass = (RIL_CDMA_SMS_ErrorClass) t;
1425
1426 status = p.readInt32(&t);
1427 rcsa.uSMSCauseCode = (int) t;
1428
1429 if (status != NO_ERROR) {
1430 goto invalid;
1431 }
1432
1433 startRequest;
1434 appendPrintBuf("%suErrorClass=%d, uTLStatus=%d, ",
1435 printBuf, rcsa.uErrorClass, rcsa.uSMSCauseCode);
1436 closeRequest;
1437
1438 printRequest(pRI->token, pRI->pCI->requestNumber);
1439
Howard Sue32dbfd2015-01-07 15:55:57 +08001440 CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa),pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001441
1442#ifdef MEMSET_FREED
1443 memset(&rcsa, 0, sizeof(rcsa));
1444#endif
1445
1446 return;
1447
1448invalid:
1449 invalidCommandBlock(pRI);
1450 return;
1451}
1452
1453static void
1454dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI) {
1455 int32_t t;
1456 status_t status;
1457 int32_t num;
1458
1459 status = p.readInt32(&num);
1460 if (status != NO_ERROR) {
1461 goto invalid;
1462 }
1463
Ethan Chend6e30652013-08-04 22:49:56 -07001464 {
1465 RIL_GSM_BroadcastSmsConfigInfo gsmBci[num];
1466 RIL_GSM_BroadcastSmsConfigInfo *gsmBciPtrs[num];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001467
Ethan Chend6e30652013-08-04 22:49:56 -07001468 startRequest;
1469 for (int i = 0 ; i < num ; i++ ) {
1470 gsmBciPtrs[i] = &gsmBci[i];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001471
Ethan Chend6e30652013-08-04 22:49:56 -07001472 status = p.readInt32(&t);
1473 gsmBci[i].fromServiceId = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001474
Ethan Chend6e30652013-08-04 22:49:56 -07001475 status = p.readInt32(&t);
1476 gsmBci[i].toServiceId = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001477
Ethan Chend6e30652013-08-04 22:49:56 -07001478 status = p.readInt32(&t);
1479 gsmBci[i].fromCodeScheme = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001480
Ethan Chend6e30652013-08-04 22:49:56 -07001481 status = p.readInt32(&t);
1482 gsmBci[i].toCodeScheme = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001483
Ethan Chend6e30652013-08-04 22:49:56 -07001484 status = p.readInt32(&t);
1485 gsmBci[i].selected = (uint8_t) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001486
Ethan Chend6e30652013-08-04 22:49:56 -07001487 appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId =%d, \
1488 fromCodeScheme=%d, toCodeScheme=%d, selected =%d]", printBuf, i,
1489 gsmBci[i].fromServiceId, gsmBci[i].toServiceId,
1490 gsmBci[i].fromCodeScheme, gsmBci[i].toCodeScheme,
1491 gsmBci[i].selected);
1492 }
1493 closeRequest;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001494
Ethan Chend6e30652013-08-04 22:49:56 -07001495 if (status != NO_ERROR) {
1496 goto invalid;
1497 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001498
Howard Sue32dbfd2015-01-07 15:55:57 +08001499 CALL_ONREQUEST(pRI->pCI->requestNumber,
Ethan Chend6e30652013-08-04 22:49:56 -07001500 gsmBciPtrs,
1501 num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *),
Howard Sue32dbfd2015-01-07 15:55:57 +08001502 pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001503
1504#ifdef MEMSET_FREED
Ethan Chend6e30652013-08-04 22:49:56 -07001505 memset(gsmBci, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo));
1506 memset(gsmBciPtrs, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001507#endif
Ethan Chend6e30652013-08-04 22:49:56 -07001508 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001509
1510 return;
1511
1512invalid:
1513 invalidCommandBlock(pRI);
1514 return;
1515}
1516
1517static void
1518dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI) {
1519 int32_t t;
1520 status_t status;
1521 int32_t num;
1522
1523 status = p.readInt32(&num);
1524 if (status != NO_ERROR) {
1525 goto invalid;
1526 }
1527
Ethan Chend6e30652013-08-04 22:49:56 -07001528 {
1529 RIL_CDMA_BroadcastSmsConfigInfo cdmaBci[num];
1530 RIL_CDMA_BroadcastSmsConfigInfo *cdmaBciPtrs[num];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001531
Ethan Chend6e30652013-08-04 22:49:56 -07001532 startRequest;
1533 for (int i = 0 ; i < num ; i++ ) {
1534 cdmaBciPtrs[i] = &cdmaBci[i];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001535
Ethan Chend6e30652013-08-04 22:49:56 -07001536 status = p.readInt32(&t);
1537 cdmaBci[i].service_category = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001538
Ethan Chend6e30652013-08-04 22:49:56 -07001539 status = p.readInt32(&t);
1540 cdmaBci[i].language = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001541
Ethan Chend6e30652013-08-04 22:49:56 -07001542 status = p.readInt32(&t);
1543 cdmaBci[i].selected = (uint8_t) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001544
Ethan Chend6e30652013-08-04 22:49:56 -07001545 appendPrintBuf("%s [%d: service_category=%d, language =%d, \
1546 entries.bSelected =%d]", printBuf, i, cdmaBci[i].service_category,
1547 cdmaBci[i].language, cdmaBci[i].selected);
1548 }
1549 closeRequest;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001550
Ethan Chend6e30652013-08-04 22:49:56 -07001551 if (status != NO_ERROR) {
1552 goto invalid;
1553 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001554
Howard Sue32dbfd2015-01-07 15:55:57 +08001555 CALL_ONREQUEST(pRI->pCI->requestNumber,
Ethan Chend6e30652013-08-04 22:49:56 -07001556 cdmaBciPtrs,
1557 num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *),
Howard Sue32dbfd2015-01-07 15:55:57 +08001558 pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001559
1560#ifdef MEMSET_FREED
Ethan Chend6e30652013-08-04 22:49:56 -07001561 memset(cdmaBci, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo));
1562 memset(cdmaBciPtrs, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001563#endif
Ethan Chend6e30652013-08-04 22:49:56 -07001564 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001565
1566 return;
1567
1568invalid:
1569 invalidCommandBlock(pRI);
1570 return;
1571}
1572
1573static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI) {
1574 RIL_CDMA_SMS_WriteArgs rcsw;
1575 int32_t t;
1576 uint32_t ut;
1577 uint8_t uct;
1578 status_t status;
1579 int32_t digitCount;
1580
1581 memset(&rcsw, 0, sizeof(rcsw));
1582
1583 status = p.readInt32(&t);
1584 rcsw.status = t;
1585
1586 status = p.readInt32(&t);
1587 rcsw.message.uTeleserviceID = (int) t;
1588
1589 status = p.read(&uct,sizeof(uct));
1590 rcsw.message.bIsServicePresent = (uint8_t) uct;
1591
1592 status = p.readInt32(&t);
1593 rcsw.message.uServicecategory = (int) t;
1594
1595 status = p.readInt32(&t);
1596 rcsw.message.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
1597
1598 status = p.readInt32(&t);
1599 rcsw.message.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
1600
1601 status = p.readInt32(&t);
1602 rcsw.message.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
1603
1604 status = p.readInt32(&t);
1605 rcsw.message.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
1606
1607 status = p.read(&uct,sizeof(uct));
1608 rcsw.message.sAddress.number_of_digits = (uint8_t) uct;
1609
1610 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_ADDRESS_MAX; digitCount ++) {
1611 status = p.read(&uct,sizeof(uct));
1612 rcsw.message.sAddress.digits[digitCount] = (uint8_t) uct;
1613 }
1614
1615 status = p.readInt32(&t);
1616 rcsw.message.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
1617
1618 status = p.read(&uct,sizeof(uct));
1619 rcsw.message.sSubAddress.odd = (uint8_t) uct;
1620
1621 status = p.read(&uct,sizeof(uct));
1622 rcsw.message.sSubAddress.number_of_digits = (uint8_t) uct;
1623
1624 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_SUBADDRESS_MAX; digitCount ++) {
1625 status = p.read(&uct,sizeof(uct));
1626 rcsw.message.sSubAddress.digits[digitCount] = (uint8_t) uct;
1627 }
1628
1629 status = p.readInt32(&t);
1630 rcsw.message.uBearerDataLen = (int) t;
1631
1632 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_BEARER_DATA_MAX; digitCount ++) {
1633 status = p.read(&uct, sizeof(uct));
1634 rcsw.message.aBearerData[digitCount] = (uint8_t) uct;
1635 }
1636
1637 if (status != NO_ERROR) {
1638 goto invalid;
1639 }
1640
1641 startRequest;
1642 appendPrintBuf("%sstatus=%d, message.uTeleserviceID=%d, message.bIsServicePresent=%d, \
1643 message.uServicecategory=%d, message.sAddress.digit_mode=%d, \
1644 message.sAddress.number_mode=%d, \
1645 message.sAddress.number_type=%d, ",
1646 printBuf, rcsw.status, rcsw.message.uTeleserviceID, rcsw.message.bIsServicePresent,
1647 rcsw.message.uServicecategory, rcsw.message.sAddress.digit_mode,
1648 rcsw.message.sAddress.number_mode,
1649 rcsw.message.sAddress.number_type);
1650 closeRequest;
1651
1652 printRequest(pRI->token, pRI->pCI->requestNumber);
1653
Howard Sue32dbfd2015-01-07 15:55:57 +08001654 CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw),pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001655
1656#ifdef MEMSET_FREED
1657 memset(&rcsw, 0, sizeof(rcsw));
1658#endif
1659
1660 return;
1661
1662invalid:
1663 invalidCommandBlock(pRI);
1664 return;
1665
1666}
1667
Ethan Chend6e30652013-08-04 22:49:56 -07001668// For backwards compatibility in RIL_REQUEST_SETUP_DATA_CALL.
1669// Version 4 of the RIL interface adds a new PDP type parameter to support
1670// IPv6 and dual-stack PDP contexts. When dealing with a previous version of
1671// RIL, remove the parameter from the request.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001672static void dispatchDataCall(Parcel& p, RequestInfo *pRI) {
Ethan Chend6e30652013-08-04 22:49:56 -07001673 // In RIL v3, REQUEST_SETUP_DATA_CALL takes 6 parameters.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001674 const int numParamsRilV3 = 6;
1675
Ethan Chend6e30652013-08-04 22:49:56 -07001676 // The first bytes of the RIL parcel contain the request number and the
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001677 // serial number - see processCommandBuffer(). Copy them over too.
1678 int pos = p.dataPosition();
1679
1680 int numParams = p.readInt32();
1681 if (s_callbacks.version < 4 && numParams > numParamsRilV3) {
1682 Parcel p2;
1683 p2.appendFrom(&p, 0, pos);
1684 p2.writeInt32(numParamsRilV3);
1685 for(int i = 0; i < numParamsRilV3; i++) {
1686 p2.writeString16(p.readString16());
1687 }
1688 p2.setDataPosition(pos);
1689 dispatchStrings(p2, pRI);
1690 } else {
1691 p.setDataPosition(pos);
1692 dispatchStrings(p, pRI);
1693 }
1694}
1695
1696// For backwards compatibility with RILs that dont support RIL_REQUEST_VOICE_RADIO_TECH.
Ethan Chend6e30652013-08-04 22:49:56 -07001697// When all RILs handle this request, this function can be removed and
1698// the request can be sent directly to the RIL using dispatchVoid.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001699static void dispatchVoiceRadioTech(Parcel& p, RequestInfo *pRI) {
Howard Sue32dbfd2015-01-07 15:55:57 +08001700 RIL_RadioState state = CALL_ONSTATEREQUEST((RIL_SOCKET_ID)pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001701
1702 if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) {
1703 RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1704 }
1705
Ethan Chend6e30652013-08-04 22:49:56 -07001706 // RILs that support RADIO_STATE_ON should support this request.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001707 if (RADIO_STATE_ON == state) {
1708 dispatchVoid(p, pRI);
1709 return;
1710 }
1711
Ethan Chend6e30652013-08-04 22:49:56 -07001712 // For Older RILs, that do not support RADIO_STATE_ON, assume that they
1713 // will not support this new request either and decode Voice Radio Technology
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001714 // from Radio State
1715 voiceRadioTech = decodeVoiceRadioTechnology(state);
1716
1717 if (voiceRadioTech < 0)
1718 RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0);
1719 else
1720 RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &voiceRadioTech, sizeof(int));
1721}
1722
Ethan Chend6e30652013-08-04 22:49:56 -07001723// For backwards compatibility in RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:.
1724// When all RILs handle this request, this function can be removed and
1725// the request can be sent directly to the RIL using dispatchVoid.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001726static void dispatchCdmaSubscriptionSource(Parcel& p, RequestInfo *pRI) {
Howard Sue32dbfd2015-01-07 15:55:57 +08001727 RIL_RadioState state = CALL_ONSTATEREQUEST((RIL_SOCKET_ID)pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001728
1729 if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) {
1730 RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1731 }
1732
1733 // RILs that support RADIO_STATE_ON should support this request.
1734 if (RADIO_STATE_ON == state) {
1735 dispatchVoid(p, pRI);
1736 return;
1737 }
1738
Ethan Chend6e30652013-08-04 22:49:56 -07001739 // For Older RILs, that do not support RADIO_STATE_ON, assume that they
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001740 // will not support this new request either and decode CDMA Subscription Source
Ethan Chend6e30652013-08-04 22:49:56 -07001741 // from Radio State
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001742 cdmaSubscriptionSource = decodeCdmaSubscriptionSource(state);
1743
1744 if (cdmaSubscriptionSource < 0)
1745 RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0);
1746 else
1747 RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &cdmaSubscriptionSource, sizeof(int));
1748}
1749
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001750static void dispatchSetInitialAttachApn(Parcel &p, RequestInfo *pRI)
1751{
1752 RIL_InitialAttachApn pf;
1753 int32_t t;
1754 status_t status;
1755
1756 memset(&pf, 0, sizeof(pf));
1757
1758 pf.apn = strdupReadString(p);
1759 pf.protocol = strdupReadString(p);
1760
1761 status = p.readInt32(&t);
1762 pf.authtype = (int) t;
1763
1764 pf.username = strdupReadString(p);
1765 pf.password = strdupReadString(p);
1766
1767 startRequest;
1768 appendPrintBuf("%sapn=%s, protocol=%s, auth_type=%d, username=%s, password=%s",
1769 printBuf, pf.apn, pf.protocol, pf.auth_type, pf.username, pf.password);
1770 closeRequest;
1771 printRequest(pRI->token, pRI->pCI->requestNumber);
1772
1773 if (status != NO_ERROR) {
1774 goto invalid;
1775 }
Howard Sue32dbfd2015-01-07 15:55:57 +08001776 CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, pRI->socket_id);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001777
1778#ifdef MEMSET_FREED
1779 memsetString(pf.apn);
1780 memsetString(pf.protocol);
1781 memsetString(pf.username);
1782 memsetString(pf.password);
1783#endif
1784
1785 free(pf.apn);
1786 free(pf.protocol);
1787 free(pf.username);
1788 free(pf.password);
1789
1790#ifdef MEMSET_FREED
1791 memset(&pf, 0, sizeof(pf));
1792#endif
1793
1794 return;
1795invalid:
1796 invalidCommandBlock(pRI);
1797 return;
1798}
1799
Howard Sue32dbfd2015-01-07 15:55:57 +08001800static void dispatchNVReadItem(Parcel &p, RequestInfo *pRI) {
1801 RIL_NV_ReadItem nvri;
1802 int32_t t;
1803 status_t status;
1804
1805 memset(&nvri, 0, sizeof(nvri));
1806
1807 status = p.readInt32(&t);
1808 nvri.itemID = (RIL_NV_Item) t;
1809
1810 if (status != NO_ERROR) {
1811 goto invalid;
1812 }
1813
1814 startRequest;
1815 appendPrintBuf("%snvri.itemID=%d, ", printBuf, nvri.itemID);
1816 closeRequest;
1817
1818 printRequest(pRI->token, pRI->pCI->requestNumber);
1819
1820 CALL_ONREQUEST(pRI->pCI->requestNumber, &nvri, sizeof(nvri), pRI, pRI->socket_id);
1821
1822#ifdef MEMSET_FREED
1823 memset(&nvri, 0, sizeof(nvri));
1824#endif
1825
1826 return;
1827
1828invalid:
1829 invalidCommandBlock(pRI);
1830 return;
1831}
1832
1833static void dispatchNVWriteItem(Parcel &p, RequestInfo *pRI) {
1834 RIL_NV_WriteItem nvwi;
1835 int32_t t;
1836 status_t status;
1837
1838 memset(&nvwi, 0, sizeof(nvwi));
1839
1840 status = p.readInt32(&t);
1841 nvwi.itemID = (RIL_NV_Item) t;
1842
1843 nvwi.value = strdupReadString(p);
1844
1845 if (status != NO_ERROR || nvwi.value == NULL) {
1846 goto invalid;
1847 }
1848
1849 startRequest;
1850 appendPrintBuf("%snvwi.itemID=%d, value=%s, ", printBuf, nvwi.itemID,
1851 nvwi.value);
1852 closeRequest;
1853
1854 printRequest(pRI->token, pRI->pCI->requestNumber);
1855
1856 CALL_ONREQUEST(pRI->pCI->requestNumber, &nvwi, sizeof(nvwi), pRI, pRI->socket_id);
1857
1858#ifdef MEMSET_FREED
1859 memsetString(nvwi.value);
1860#endif
1861
1862 free(nvwi.value);
1863
1864#ifdef MEMSET_FREED
1865 memset(&nvwi, 0, sizeof(nvwi));
1866#endif
1867
1868 return;
1869
1870invalid:
1871 invalidCommandBlock(pRI);
1872 return;
1873}
1874
1875
1876static void dispatchUiccSubscripton(Parcel &p, RequestInfo *pRI) {
1877 RIL_SelectUiccSub uicc_sub;
1878 status_t status;
1879 int32_t t;
1880 memset(&uicc_sub, 0, sizeof(uicc_sub));
1881
1882 status = p.readInt32(&t);
1883 if (status != NO_ERROR) {
1884 goto invalid;
1885 }
1886 uicc_sub.slot = (int) t;
1887
1888 status = p.readInt32(&t);
1889 if (status != NO_ERROR) {
1890 goto invalid;
1891 }
1892 uicc_sub.app_index = (int) t;
1893
1894 status = p.readInt32(&t);
1895 if (status != NO_ERROR) {
1896 goto invalid;
1897 }
1898 uicc_sub.sub_type = (RIL_SubscriptionType) t;
1899
1900 status = p.readInt32(&t);
1901 if (status != NO_ERROR) {
1902 goto invalid;
1903 }
1904 uicc_sub.act_status = (RIL_UiccSubActStatus) t;
1905
1906 startRequest;
1907 appendPrintBuf("slot=%d, app_index=%d, act_status = %d", uicc_sub.slot, uicc_sub.app_index,
1908 uicc_sub.act_status);
1909 RLOGD("dispatchUiccSubscription, slot=%d, app_index=%d, act_status = %d", uicc_sub.slot,
1910 uicc_sub.app_index, uicc_sub.act_status);
1911 closeRequest;
1912 printRequest(pRI->token, pRI->pCI->requestNumber);
1913
1914 CALL_ONREQUEST(pRI->pCI->requestNumber, &uicc_sub, sizeof(uicc_sub), pRI, pRI->socket_id);
1915
1916#ifdef MEMSET_FREED
1917 memset(&uicc_sub, 0, sizeof(uicc_sub));
1918#endif
1919 return;
1920
1921invalid:
1922 invalidCommandBlock(pRI);
1923 return;
1924}
1925
1926static void dispatchSimAuthentication(Parcel &p, RequestInfo *pRI)
1927{
1928 RIL_SimAuthentication pf;
1929 int32_t t;
1930 status_t status;
1931
1932 memset(&pf, 0, sizeof(pf));
1933
1934 status = p.readInt32(&t);
1935 pf.authContext = (int) t;
1936 pf.authData = strdupReadString(p);
1937 pf.aid = strdupReadString(p);
1938
1939 startRequest;
1940 appendPrintBuf("authContext=%s, authData=%s, aid=%s", pf.authContext, pf.authData, pf.aid);
1941 closeRequest;
1942 printRequest(pRI->token, pRI->pCI->requestNumber);
1943
1944 if (status != NO_ERROR) {
1945 goto invalid;
1946 }
1947 CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, pRI->socket_id);
1948
1949#ifdef MEMSET_FREED
1950 memsetString(pf.authData);
1951 memsetString(pf.aid);
1952#endif
1953
1954 free(pf.authData);
1955 free(pf.aid);
1956
1957#ifdef MEMSET_FREED
1958 memset(&pf, 0, sizeof(pf));
1959#endif
1960
1961 return;
1962invalid:
1963 invalidCommandBlock(pRI);
1964 return;
1965}
1966
1967static void dispatchDataProfile(Parcel &p, RequestInfo *pRI) {
1968 int32_t t;
1969 status_t status;
1970 int32_t num;
1971
1972 status = p.readInt32(&num);
1973 if (status != NO_ERROR) {
1974 goto invalid;
1975 }
1976
1977 {
1978 RIL_DataProfileInfo dataProfiles[num];
1979 RIL_DataProfileInfo *dataProfilePtrs[num];
1980
1981 startRequest;
1982 for (int i = 0 ; i < num ; i++ ) {
1983 dataProfilePtrs[i] = &dataProfiles[i];
1984
1985 status = p.readInt32(&t);
1986 dataProfiles[i].profileId = (int) t;
1987
1988 dataProfiles[i].apn = strdupReadString(p);
1989 dataProfiles[i].protocol = strdupReadString(p);
1990 status = p.readInt32(&t);
1991 dataProfiles[i].authType = (int) t;
1992
1993 dataProfiles[i].user = strdupReadString(p);
1994 dataProfiles[i].password = strdupReadString(p);
1995
1996 status = p.readInt32(&t);
1997 dataProfiles[i].type = (int) t;
1998
1999 status = p.readInt32(&t);
2000 dataProfiles[i].maxConnsTime = (int) t;
2001 status = p.readInt32(&t);
2002 dataProfiles[i].maxConns = (int) t;
2003 status = p.readInt32(&t);
2004 dataProfiles[i].waitTime = (int) t;
2005
2006 status = p.readInt32(&t);
2007 dataProfiles[i].enabled = (int) t;
2008
2009 appendPrintBuf("%s [%d: profileId=%d, apn =%s, protocol =%s, authType =%d, \
2010 user =%s, password =%s, type =%d, maxConnsTime =%d, maxConns =%d, \
2011 waitTime =%d, enabled =%d]", printBuf, i, dataProfiles[i].profileId,
2012 dataProfiles[i].apn, dataProfiles[i].protocol, dataProfiles[i].authType,
2013 dataProfiles[i].user, dataProfiles[i].password, dataProfiles[i].type,
2014 dataProfiles[i].maxConnsTime, dataProfiles[i].maxConns,
2015 dataProfiles[i].waitTime, dataProfiles[i].enabled);
2016 }
2017 closeRequest;
2018 printRequest(pRI->token, pRI->pCI->requestNumber);
2019
2020 if (status != NO_ERROR) {
2021 goto invalid;
2022 }
2023 CALL_ONREQUEST(pRI->pCI->requestNumber,
2024 dataProfilePtrs,
2025 num * sizeof(RIL_DataProfileInfo *),
2026 pRI, pRI->socket_id);
2027
2028#ifdef MEMSET_FREED
2029 memset(dataProfiles, 0, num * sizeof(RIL_DataProfileInfo));
2030 memset(dataProfilePtrs, 0, num * sizeof(RIL_DataProfileInfo *));
2031#endif
2032 }
2033
2034 return;
2035
2036invalid:
2037 invalidCommandBlock(pRI);
2038 return;
2039}
2040
Howard Subd82ef12015-04-12 10:25:05 +02002041static void dispatchRadioCapability(Parcel &p, RequestInfo *pRI){
2042 RIL_RadioCapability rc;
2043 int32_t t;
2044 status_t status;
2045
2046 memset (&rc, 0, sizeof(RIL_RadioCapability));
2047
2048 status = p.readInt32(&t);
2049 rc.version = (int)t;
2050 if (status != NO_ERROR) {
2051 goto invalid;
2052 }
2053
2054 status = p.readInt32(&t);
2055 rc.session= (int)t;
2056 if (status != NO_ERROR) {
2057 goto invalid;
2058 }
2059
2060 status = p.readInt32(&t);
2061 rc.phase= (int)t;
2062 if (status != NO_ERROR) {
2063 goto invalid;
2064 }
2065
2066 status = p.readInt32(&t);
2067 rc.rat = (int)t;
2068 if (status != NO_ERROR) {
2069 goto invalid;
2070 }
2071
2072 status = readStringFromParcelInplace(p, rc.logicalModemUuid, sizeof(rc.logicalModemUuid));
2073 if (status != NO_ERROR) {
2074 goto invalid;
2075 }
2076
2077 status = p.readInt32(&t);
2078 rc.status = (int)t;
2079
2080 if (status != NO_ERROR) {
2081 goto invalid;
2082 }
2083
2084 startRequest;
2085 appendPrintBuf("%s [version:%d, session:%d, phase:%d, rat:%d, \
2086 logicalModemUuid:%s, status:%d", printBuf, rc.version, rc.session
2087 rc.phase, rc.rat, rc.logicalModemUuid, rc.session);
2088
2089 closeRequest;
2090 printRequest(pRI->token, pRI->pCI->requestNumber);
2091
2092 CALL_ONREQUEST(pRI->pCI->requestNumber,
2093 &rc,
2094 sizeof(RIL_RadioCapability),
2095 pRI, pRI->socket_id);
2096 return;
2097invalid:
2098 invalidCommandBlock(pRI);
2099 return;
2100}
2101
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002102static int
2103blockingWrite(int fd, const void *buffer, size_t len) {
2104 size_t writeOffset = 0;
2105 const uint8_t *toWrite;
2106
2107 toWrite = (const uint8_t *)buffer;
2108
2109 while (writeOffset < len) {
2110 ssize_t written;
2111 do {
2112 written = write (fd, toWrite + writeOffset,
2113 len - writeOffset);
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002114 } while (written < 0 && ((errno == EINTR) || (errno == EAGAIN)));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002115
2116 if (written >= 0) {
2117 writeOffset += written;
2118 } else { // written < 0
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002119 RLOGE ("RIL Response: unexpected error on write errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002120 close(fd);
2121 return -1;
2122 }
2123 }
2124
2125 return 0;
2126}
2127
2128static int
Howard Sue32dbfd2015-01-07 15:55:57 +08002129sendResponseRaw (const void *data, size_t dataSize, RIL_SOCKET_ID socket_id) {
2130 int fd = s_ril_param_socket.fdCommand;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002131 int ret;
2132 uint32_t header;
Howard Sue32dbfd2015-01-07 15:55:57 +08002133 pthread_mutex_t * writeMutexHook = &s_writeMutex;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002134
Howard Sue32dbfd2015-01-07 15:55:57 +08002135 RLOGE("Send Response to %s", rilSocketIdToString(socket_id));
2136
2137#if (SIM_COUNT >= 2)
2138 if (socket_id == RIL_SOCKET_2) {
2139 fd = s_ril_param_socket2.fdCommand;
2140 writeMutexHook = &s_writeMutex_socket2;
2141 }
2142#if (SIM_COUNT >= 3)
2143 else if (socket_id == RIL_SOCKET_3) {
2144 fd = s_ril_param_socket3.fdCommand;
2145 writeMutexHook = &s_writeMutex_socket3;
2146 }
2147#endif
2148#if (SIM_COUNT >= 4)
2149 else if (socket_id == RIL_SOCKET_4) {
2150 fd = s_ril_param_socket4.fdCommand;
2151 writeMutexHook = &s_writeMutex_socket4;
2152 }
2153#endif
2154#endif
2155 if (fd < 0) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002156 return -1;
2157 }
2158
Howard Subd82ef12015-04-12 10:25:05 +02002159 if (dataSize > MAX_COMMAND_BYTES) {
2160 RLOGE("RIL: packet larger than %u (%u)",
2161 MAX_COMMAND_BYTES, (unsigned int )dataSize);
2162
2163 return -1;
2164 }
2165
Howard Sue32dbfd2015-01-07 15:55:57 +08002166 pthread_mutex_lock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002167
2168 header = htonl(dataSize);
2169
2170 ret = blockingWrite(fd, (void *)&header, sizeof(header));
2171
2172 if (ret < 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002173 pthread_mutex_unlock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002174 return ret;
2175 }
2176
2177 ret = blockingWrite(fd, data, dataSize);
2178
2179 if (ret < 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002180 pthread_mutex_unlock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002181 return ret;
2182 }
2183
Howard Sue32dbfd2015-01-07 15:55:57 +08002184 pthread_mutex_unlock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002185
2186 return 0;
2187}
2188
2189static int
Howard Sue32dbfd2015-01-07 15:55:57 +08002190sendResponse (Parcel &p, RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002191 printResponse;
Howard Sue32dbfd2015-01-07 15:55:57 +08002192 return sendResponseRaw(p.data(), p.dataSize(), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002193}
2194
Howard Sue32dbfd2015-01-07 15:55:57 +08002195/** response is an int* pointing to an array of ints */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002196
2197static int
2198responseInts(Parcel &p, void *response, size_t responselen) {
2199 int numInts;
2200
2201 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002202 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002203 return RIL_ERRNO_INVALID_RESPONSE;
2204 }
2205 if (responselen % sizeof(int) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002206 RLOGE("responseInts: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002207 (int)responselen, (int)sizeof(int));
2208 return RIL_ERRNO_INVALID_RESPONSE;
2209 }
2210
2211 int *p_int = (int *) response;
2212
Howard Sue32dbfd2015-01-07 15:55:57 +08002213 numInts = responselen / sizeof(int);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002214 p.writeInt32 (numInts);
2215
2216 /* each int*/
2217 startResponse;
2218 for (int i = 0 ; i < numInts ; i++) {
2219 appendPrintBuf("%s%d,", printBuf, p_int[i]);
2220 p.writeInt32(p_int[i]);
2221 }
2222 removeLastChar;
2223 closeResponse;
2224
2225 return 0;
2226}
2227
Daniel Hillenbrandd0b84162015-04-12 11:53:23 +02002228static int
2229responseIntsGetPreferredNetworkType(Parcel &p, void *response, size_t responselen) {
2230 int numInts;
2231
2232 if (response == NULL && responselen != 0) {
2233 RLOGE("invalid response: NULL");
2234 return RIL_ERRNO_INVALID_RESPONSE;
2235 }
2236 if (responselen % sizeof(int) != 0) {
2237 RLOGE("responseInts: invalid response length %d expected multiple of %d\n",
2238 (int)responselen, (int)sizeof(int));
2239 return RIL_ERRNO_INVALID_RESPONSE;
2240 }
2241
2242 int *p_int = (int *) response;
2243
2244 numInts = responselen / sizeof(int);
2245 p.writeInt32 (numInts);
2246
2247 /* each int*/
2248 startResponse;
2249 for (int i = 0 ; i < numInts ; i++) {
2250 if (i == 0 && p_int[0] == 7) {
2251 RLOGD("REQUEST_GET_PREFERRED_NETWORK_TYPE: NETWORK_MODE_GLOBAL => NETWORK_MODE_WCDMA_PREF");
2252 p_int[0] = 0;
2253 }
2254 appendPrintBuf("%s%d,", printBuf, p_int[i]);
2255 p.writeInt32(p_int[i]);
2256 }
2257 removeLastChar;
2258 closeResponse;
2259
2260 return 0;
2261}
2262
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002263/** response is a char **, pointing to an array of char *'s
2264 The parcel will begin with the version */
2265static int responseStringsWithVersion(int version, Parcel &p, void *response, size_t responselen) {
2266 p.writeInt32(version);
2267 return responseStrings(p, response, responselen);
2268}
2269
2270/** response is a char **, pointing to an array of char *'s */
2271static int responseStrings(Parcel &p, void *response, size_t responselen) {
2272 return responseStrings(p, response, responselen, false);
2273}
2274
Utkarsh Guptaf7a63e52015-05-10 16:53:37 +05302275static int responseStringsNetworks(Parcel &p, void *response, size_t responselen) {
2276 return responseStrings(p, response, responselen, true);
2277}
2278
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002279/** response is a char **, pointing to an array of char *'s */
2280static int responseStrings(Parcel &p, void *response, size_t responselen, bool network_search) {
2281 int numStrings;
2282
2283 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002284 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002285 return RIL_ERRNO_INVALID_RESPONSE;
2286 }
2287 if (responselen % sizeof(char *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002288 RLOGE("responseStrings: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002289 (int)responselen, (int)sizeof(char *));
2290 return RIL_ERRNO_INVALID_RESPONSE;
2291 }
2292
2293 if (response == NULL) {
2294 p.writeInt32 (0);
2295 } else {
2296 char **p_cur = (char **) response;
2297
2298 numStrings = responselen / sizeof(char *);
Utkarsh Guptaf7a63e52015-05-10 16:53:37 +05302299 if (network_search) {
2300 p.writeInt32 ((numStrings / 5) * 4);
2301 } else {
2302 p.writeInt32 (numStrings);
2303 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002304
2305 /* each string*/
2306 startResponse;
2307 for (int i = 0 ; i < numStrings ; i++) {
NBruderman72edd422015-06-08 15:54:55 +03002308 if (network_search && ((i + 1) % 5 == 0))
Utkarsh Guptaf7a63e52015-05-10 16:53:37 +05302309 continue;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002310 appendPrintBuf("%s%s,", printBuf, (char*)p_cur[i]);
2311 writeStringToParcel (p, p_cur[i]);
2312 }
2313 removeLastChar;
2314 closeResponse;
2315 }
2316 return 0;
2317}
2318
Howard Subd82ef12015-04-12 10:25:05 +02002319
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002320/**
2321 * NULL strings are accepted
2322 * FIXME currently ignores responselen
2323 */
2324static int responseString(Parcel &p, void *response, size_t responselen) {
2325 /* one string only */
2326 startResponse;
2327 appendPrintBuf("%s%s", printBuf, (char*)response);
2328 closeResponse;
2329
2330 writeStringToParcel(p, (const char *)response);
2331
2332 return 0;
2333}
2334
2335static int responseVoid(Parcel &p, void *response, size_t responselen) {
2336 startResponse;
2337 removeLastChar;
2338 return 0;
2339}
2340
2341static int responseCallList(Parcel &p, void *response, size_t responselen) {
2342 int num;
2343
2344 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002345 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002346 return RIL_ERRNO_INVALID_RESPONSE;
2347 }
2348
2349 if (responselen % sizeof (RIL_Call *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002350 RLOGE("responseCallList: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002351 (int)responselen, (int)sizeof (RIL_Call *));
2352 return RIL_ERRNO_INVALID_RESPONSE;
2353 }
2354
2355 startResponse;
2356 /* number of call info's */
2357 num = responselen / sizeof(RIL_Call *);
2358 p.writeInt32(num);
2359
2360 for (int i = 0 ; i < num ; i++) {
2361 RIL_Call *p_cur = ((RIL_Call **) response)[i];
2362 /* each call info */
2363 p.writeInt32(p_cur->state);
2364 p.writeInt32(p_cur->index);
2365 p.writeInt32(p_cur->toa);
2366 p.writeInt32(p_cur->isMpty);
2367 p.writeInt32(p_cur->isMT);
2368 p.writeInt32(p_cur->als);
2369 p.writeInt32(p_cur->isVoice);
Andreas Schneider29472682015-01-01 19:00:04 +01002370
2371#ifdef MODEM_TYPE_XMM7260
2372 p.writeInt32(p_cur->isVideo);
2373
2374 /* Pass CallDetails */
2375 p.writeInt32(0);
2376 p.writeInt32(0);
2377 writeStringToParcel(p, "");
2378#endif
2379
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002380 p.writeInt32(p_cur->isVoicePrivacy);
2381 writeStringToParcel(p, p_cur->number);
2382 p.writeInt32(p_cur->numberPresentation);
2383 writeStringToParcel(p, p_cur->name);
2384 p.writeInt32(p_cur->namePresentation);
2385 // Remove when partners upgrade to version 3
2386 if ((s_callbacks.version < 3) || (p_cur->uusInfo == NULL || p_cur->uusInfo->uusData == NULL)) {
2387 p.writeInt32(0); /* UUS Information is absent */
2388 } else {
2389 RIL_UUS_Info *uusInfo = p_cur->uusInfo;
2390 p.writeInt32(1); /* UUS Information is present */
2391 p.writeInt32(uusInfo->uusType);
2392 p.writeInt32(uusInfo->uusDcs);
2393 p.writeInt32(uusInfo->uusLength);
2394 p.write(uusInfo->uusData, uusInfo->uusLength);
2395 }
2396 appendPrintBuf("%s[id=%d,%s,toa=%d,",
2397 printBuf,
2398 p_cur->index,
2399 callStateToString(p_cur->state),
2400 p_cur->toa);
2401 appendPrintBuf("%s%s,%s,als=%d,%s,%s,",
2402 printBuf,
2403 (p_cur->isMpty)?"conf":"norm",
2404 (p_cur->isMT)?"mt":"mo",
2405 p_cur->als,
2406 (p_cur->isVoice)?"voc":"nonvoc",
2407 (p_cur->isVoicePrivacy)?"evp":"noevp");
Andreas Schneider29472682015-01-01 19:00:04 +01002408#ifdef MODEM_TYPE_XMM7260
2409 appendPrintBuf("%s,%s,",
2410 printBuf,
2411 (p_cur->isVideo) ? "vid" : "novid");
2412#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002413 appendPrintBuf("%s%s,cli=%d,name='%s',%d]",
2414 printBuf,
2415 p_cur->number,
2416 p_cur->numberPresentation,
2417 p_cur->name,
2418 p_cur->namePresentation);
2419 }
2420 removeLastChar;
2421 closeResponse;
2422
2423 return 0;
2424}
2425
2426static int responseSMS(Parcel &p, void *response, size_t responselen) {
2427 if (response == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002428 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002429 return RIL_ERRNO_INVALID_RESPONSE;
2430 }
2431
2432 if (responselen != sizeof (RIL_SMS_Response) ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002433 RLOGE("invalid response length %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002434 (int)responselen, (int)sizeof (RIL_SMS_Response));
2435 return RIL_ERRNO_INVALID_RESPONSE;
2436 }
2437
2438 RIL_SMS_Response *p_cur = (RIL_SMS_Response *) response;
2439
2440 p.writeInt32(p_cur->messageRef);
2441 writeStringToParcel(p, p_cur->ackPDU);
2442 p.writeInt32(p_cur->errorCode);
2443
2444 startResponse;
2445 appendPrintBuf("%s%d,%s,%d", printBuf, p_cur->messageRef,
2446 (char*)p_cur->ackPDU, p_cur->errorCode);
2447 closeResponse;
2448
2449 return 0;
2450}
2451
2452static int responseDataCallListV4(Parcel &p, void *response, size_t responselen)
2453{
2454 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002455 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002456 return RIL_ERRNO_INVALID_RESPONSE;
2457 }
2458
2459 if (responselen % sizeof(RIL_Data_Call_Response_v4) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002460 RLOGE("responseDataCallListV4: invalid response length %d expected multiple of %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002461 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v4));
2462 return RIL_ERRNO_INVALID_RESPONSE;
2463 }
2464
Howard Sue32dbfd2015-01-07 15:55:57 +08002465 // Write version
2466 p.writeInt32(4);
2467
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002468 int num = responselen / sizeof(RIL_Data_Call_Response_v4);
2469 p.writeInt32(num);
2470
2471 RIL_Data_Call_Response_v4 *p_cur = (RIL_Data_Call_Response_v4 *) response;
2472 startResponse;
2473 int i;
2474 for (i = 0; i < num; i++) {
2475 p.writeInt32(p_cur[i].cid);
2476 p.writeInt32(p_cur[i].active);
2477 writeStringToParcel(p, p_cur[i].type);
2478 // apn is not used, so don't send.
2479 writeStringToParcel(p, p_cur[i].address);
2480 appendPrintBuf("%s[cid=%d,%s,%s,%s],", printBuf,
2481 p_cur[i].cid,
2482 (p_cur[i].active==0)?"down":"up",
2483 (char*)p_cur[i].type,
2484 (char*)p_cur[i].address);
2485 }
2486 removeLastChar;
2487 closeResponse;
2488
2489 return 0;
2490}
2491
Howard Sue32dbfd2015-01-07 15:55:57 +08002492static int responseDataCallListV6(Parcel &p, void *response, size_t responselen)
2493{
2494 if (response == NULL && responselen != 0) {
2495 RLOGE("invalid response: NULL");
2496 return RIL_ERRNO_INVALID_RESPONSE;
2497 }
2498
2499 if (responselen % sizeof(RIL_Data_Call_Response_v6) != 0) {
2500 RLOGE("responseDataCallListV6: invalid response length %d expected multiple of %d",
2501 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v6));
2502 return RIL_ERRNO_INVALID_RESPONSE;
2503 }
2504
2505 // Write version
2506 p.writeInt32(6);
2507
2508 int num = responselen / sizeof(RIL_Data_Call_Response_v6);
2509 p.writeInt32(num);
2510
2511 RIL_Data_Call_Response_v6 *p_cur = (RIL_Data_Call_Response_v6 *) response;
2512 startResponse;
2513 int i;
2514 for (i = 0; i < num; i++) {
2515 p.writeInt32((int)p_cur[i].status);
2516 p.writeInt32(p_cur[i].suggestedRetryTime);
2517 p.writeInt32(p_cur[i].cid);
2518 p.writeInt32(p_cur[i].active);
2519 writeStringToParcel(p, p_cur[i].type);
2520 writeStringToParcel(p, p_cur[i].ifname);
2521 writeStringToParcel(p, p_cur[i].addresses);
2522 writeStringToParcel(p, p_cur[i].dnses);
2523 writeStringToParcel(p, p_cur[i].addresses);
2524 appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s],", printBuf,
2525 p_cur[i].status,
2526 p_cur[i].suggestedRetryTime,
2527 p_cur[i].cid,
2528 (p_cur[i].active==0)?"down":"up",
2529 (char*)p_cur[i].type,
2530 (char*)p_cur[i].ifname,
2531 (char*)p_cur[i].addresses,
2532 (char*)p_cur[i].dnses,
2533 (char*)p_cur[i].addresses);
2534 }
2535 removeLastChar;
2536 closeResponse;
2537
2538 return 0;
2539}
2540
Howard Subd82ef12015-04-12 10:25:05 +02002541static int responseDataCallListV9(Parcel &p, void *response, size_t responselen)
2542{
2543 if (response == NULL && responselen != 0) {
2544 RLOGE("invalid response: NULL");
2545 return RIL_ERRNO_INVALID_RESPONSE;
2546 }
2547
2548 if (responselen % sizeof(RIL_Data_Call_Response_v9) != 0) {
2549 RLOGE("responseDataCallListV9: invalid response length %d expected multiple of %d",
2550 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v9));
2551 return RIL_ERRNO_INVALID_RESPONSE;
2552 }
2553
2554 // Write version
2555 p.writeInt32(10);
2556
2557 int num = responselen / sizeof(RIL_Data_Call_Response_v9);
2558 p.writeInt32(num);
2559
2560 RIL_Data_Call_Response_v9 *p_cur = (RIL_Data_Call_Response_v9 *) response;
2561 startResponse;
2562 int i;
2563 for (i = 0; i < num; i++) {
2564 p.writeInt32((int)p_cur[i].status);
2565 p.writeInt32(p_cur[i].suggestedRetryTime);
2566 p.writeInt32(p_cur[i].cid);
2567 p.writeInt32(p_cur[i].active);
2568 writeStringToParcel(p, p_cur[i].type);
2569 writeStringToParcel(p, p_cur[i].ifname);
2570 writeStringToParcel(p, p_cur[i].addresses);
2571 writeStringToParcel(p, p_cur[i].dnses);
2572 writeStringToParcel(p, p_cur[i].gateways);
2573 writeStringToParcel(p, p_cur[i].pcscf);
2574 appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s],", printBuf,
2575 p_cur[i].status,
2576 p_cur[i].suggestedRetryTime,
2577 p_cur[i].cid,
2578 (p_cur[i].active==0)?"down":"up",
2579 (char*)p_cur[i].type,
2580 (char*)p_cur[i].ifname,
2581 (char*)p_cur[i].addresses,
2582 (char*)p_cur[i].dnses,
2583 (char*)p_cur[i].gateways,
2584 (char*)p_cur[i].pcscf);
2585 }
2586 removeLastChar;
2587 closeResponse;
2588
2589 return 0;
2590}
2591
2592
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002593static int responseDataCallList(Parcel &p, void *response, size_t responselen)
2594{
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002595 if (s_callbacks.version < 5) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002596 RLOGD("responseDataCallList: v4");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002597 return responseDataCallListV4(p, response, responselen);
Howard Subd82ef12015-04-12 10:25:05 +02002598 } else if (responselen % sizeof(RIL_Data_Call_Response_v6) == 0) {
2599 return responseDataCallListV6(p, response, responselen);
2600 } else if (responselen % sizeof(RIL_Data_Call_Response_v9) == 0) {
2601 return responseDataCallListV9(p, response, responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002602 } else {
2603 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002604 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002605 return RIL_ERRNO_INVALID_RESPONSE;
2606 }
2607
Howard Subd82ef12015-04-12 10:25:05 +02002608 if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) {
2609 RLOGE("invalid response length %d expected multiple of %d",
2610 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v11));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002611 return RIL_ERRNO_INVALID_RESPONSE;
2612 }
2613
Howard Sue32dbfd2015-01-07 15:55:57 +08002614 // Write version
Howard Subd82ef12015-04-12 10:25:05 +02002615 p.writeInt32(11);
Howard Sue32dbfd2015-01-07 15:55:57 +08002616
Howard Subd82ef12015-04-12 10:25:05 +02002617 int num = responselen / sizeof(RIL_Data_Call_Response_v11);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002618 p.writeInt32(num);
2619
Howard Subd82ef12015-04-12 10:25:05 +02002620 RIL_Data_Call_Response_v11 *p_cur = (RIL_Data_Call_Response_v11 *) response;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002621 startResponse;
2622 int i;
2623 for (i = 0; i < num; i++) {
2624 p.writeInt32((int)p_cur[i].status);
2625 p.writeInt32(p_cur[i].suggestedRetryTime);
2626 p.writeInt32(p_cur[i].cid);
2627 p.writeInt32(p_cur[i].active);
2628 writeStringToParcel(p, p_cur[i].type);
2629 writeStringToParcel(p, p_cur[i].ifname);
2630 writeStringToParcel(p, p_cur[i].addresses);
2631 writeStringToParcel(p, p_cur[i].dnses);
Howard Sue32dbfd2015-01-07 15:55:57 +08002632 writeStringToParcel(p, p_cur[i].gateways);
2633 writeStringToParcel(p, p_cur[i].pcscf);
Howard Subd82ef12015-04-12 10:25:05 +02002634 p.writeInt32(p_cur[i].mtu);
2635 appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s,mtu=%d],", printBuf,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002636 p_cur[i].status,
2637 p_cur[i].suggestedRetryTime,
2638 p_cur[i].cid,
2639 (p_cur[i].active==0)?"down":"up",
2640 (char*)p_cur[i].type,
2641 (char*)p_cur[i].ifname,
2642 (char*)p_cur[i].addresses,
2643 (char*)p_cur[i].dnses,
Howard Sue32dbfd2015-01-07 15:55:57 +08002644 (char*)p_cur[i].gateways,
Howard Subd82ef12015-04-12 10:25:05 +02002645 (char*)p_cur[i].pcscf,
2646 p_cur[i].mtu);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002647 }
2648 removeLastChar;
2649 closeResponse;
2650 }
2651
2652 return 0;
2653}
2654
2655static int responseSetupDataCall(Parcel &p, void *response, size_t responselen)
2656{
2657 if (s_callbacks.version < 5) {
2658 return responseStringsWithVersion(s_callbacks.version, p, response, responselen);
2659 } else {
2660 return responseDataCallList(p, response, responselen);
2661 }
2662}
2663
2664static int responseRaw(Parcel &p, void *response, size_t responselen) {
2665 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002666 RLOGE("invalid response: NULL with responselen != 0");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002667 return RIL_ERRNO_INVALID_RESPONSE;
2668 }
2669
2670 // The java code reads -1 size as null byte array
2671 if (response == NULL) {
2672 p.writeInt32(-1);
2673 } else {
2674 p.writeInt32(responselen);
2675 p.write(response, responselen);
2676 }
2677
2678 return 0;
2679}
2680
2681
2682static int responseSIM_IO(Parcel &p, void *response, size_t responselen) {
2683 if (response == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002684 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002685 return RIL_ERRNO_INVALID_RESPONSE;
2686 }
2687
2688 if (responselen != sizeof (RIL_SIM_IO_Response) ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002689 RLOGE("invalid response length was %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002690 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
2691 return RIL_ERRNO_INVALID_RESPONSE;
2692 }
2693
2694 RIL_SIM_IO_Response *p_cur = (RIL_SIM_IO_Response *) response;
2695 p.writeInt32(p_cur->sw1);
2696 p.writeInt32(p_cur->sw2);
2697 writeStringToParcel(p, p_cur->simResponse);
2698
2699 startResponse;
2700 appendPrintBuf("%ssw1=0x%X,sw2=0x%X,%s", printBuf, p_cur->sw1, p_cur->sw2,
2701 (char*)p_cur->simResponse);
2702 closeResponse;
2703
2704
2705 return 0;
2706}
2707
2708static int responseCallForwards(Parcel &p, void *response, size_t responselen) {
2709 int num;
2710
2711 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002712 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002713 return RIL_ERRNO_INVALID_RESPONSE;
2714 }
2715
2716 if (responselen % sizeof(RIL_CallForwardInfo *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002717 RLOGE("responseCallForwards: invalid response length %d expected multiple of %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002718 (int)responselen, (int)sizeof(RIL_CallForwardInfo *));
2719 return RIL_ERRNO_INVALID_RESPONSE;
2720 }
2721
2722 /* number of call info's */
2723 num = responselen / sizeof(RIL_CallForwardInfo *);
2724 p.writeInt32(num);
2725
2726 startResponse;
2727 for (int i = 0 ; i < num ; i++) {
2728 RIL_CallForwardInfo *p_cur = ((RIL_CallForwardInfo **) response)[i];
2729
2730 p.writeInt32(p_cur->status);
2731 p.writeInt32(p_cur->reason);
2732 p.writeInt32(p_cur->serviceClass);
2733 p.writeInt32(p_cur->toa);
2734 writeStringToParcel(p, p_cur->number);
2735 p.writeInt32(p_cur->timeSeconds);
2736 appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
2737 (p_cur->status==1)?"enable":"disable",
2738 p_cur->reason, p_cur->serviceClass, p_cur->toa,
2739 (char*)p_cur->number,
2740 p_cur->timeSeconds);
2741 }
2742 removeLastChar;
2743 closeResponse;
2744
2745 return 0;
2746}
2747
2748static int responseSsn(Parcel &p, void *response, size_t responselen) {
2749 if (response == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002750 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002751 return RIL_ERRNO_INVALID_RESPONSE;
2752 }
2753
2754 if (responselen != sizeof(RIL_SuppSvcNotification)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002755 RLOGE("invalid response length was %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002756 (int)responselen, (int)sizeof (RIL_SuppSvcNotification));
2757 return RIL_ERRNO_INVALID_RESPONSE;
2758 }
2759
2760 RIL_SuppSvcNotification *p_cur = (RIL_SuppSvcNotification *) response;
2761 p.writeInt32(p_cur->notificationType);
2762 p.writeInt32(p_cur->code);
2763 p.writeInt32(p_cur->index);
2764 p.writeInt32(p_cur->type);
2765 writeStringToParcel(p, p_cur->number);
2766
2767 startResponse;
2768 appendPrintBuf("%s%s,code=%d,id=%d,type=%d,%s", printBuf,
2769 (p_cur->notificationType==0)?"mo":"mt",
2770 p_cur->code, p_cur->index, p_cur->type,
2771 (char*)p_cur->number);
2772 closeResponse;
2773
2774 return 0;
2775}
2776
2777static int responseCellList(Parcel &p, void *response, size_t responselen) {
2778 int num;
2779
2780 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002781 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002782 return RIL_ERRNO_INVALID_RESPONSE;
2783 }
2784
2785 if (responselen % sizeof (RIL_NeighboringCell *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002786 RLOGE("responseCellList: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002787 (int)responselen, (int)sizeof (RIL_NeighboringCell *));
2788 return RIL_ERRNO_INVALID_RESPONSE;
2789 }
2790
2791 startResponse;
2792 /* number of records */
2793 num = responselen / sizeof(RIL_NeighboringCell *);
2794 p.writeInt32(num);
2795
2796 for (int i = 0 ; i < num ; i++) {
2797 RIL_NeighboringCell *p_cur = ((RIL_NeighboringCell **) response)[i];
2798
2799 p.writeInt32(p_cur->rssi);
2800 writeStringToParcel (p, p_cur->cid);
2801
2802 appendPrintBuf("%s[cid=%s,rssi=%d],", printBuf,
2803 p_cur->cid, p_cur->rssi);
2804 }
2805 removeLastChar;
2806 closeResponse;
2807
2808 return 0;
2809}
2810
2811/**
2812 * Marshall the signalInfoRecord into the parcel if it exists.
2813 */
2814static void marshallSignalInfoRecord(Parcel &p,
2815 RIL_CDMA_SignalInfoRecord &p_signalInfoRecord) {
2816 p.writeInt32(p_signalInfoRecord.isPresent);
2817 p.writeInt32(p_signalInfoRecord.signalType);
2818 p.writeInt32(p_signalInfoRecord.alertPitch);
2819 p.writeInt32(p_signalInfoRecord.signal);
2820}
2821
2822static int responseCdmaInformationRecords(Parcel &p,
2823 void *response, size_t responselen) {
2824 int num;
2825 char* string8 = NULL;
2826 int buffer_lenght;
2827 RIL_CDMA_InformationRecord *infoRec;
2828
2829 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002830 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002831 return RIL_ERRNO_INVALID_RESPONSE;
2832 }
2833
2834 if (responselen != sizeof (RIL_CDMA_InformationRecords)) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002835 RLOGE("responseCdmaInformationRecords: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002836 (int)responselen, (int)sizeof (RIL_CDMA_InformationRecords *));
2837 return RIL_ERRNO_INVALID_RESPONSE;
2838 }
2839
2840 RIL_CDMA_InformationRecords *p_cur =
2841 (RIL_CDMA_InformationRecords *) response;
2842 num = MIN(p_cur->numberOfInfoRecs, RIL_CDMA_MAX_NUMBER_OF_INFO_RECS);
2843
2844 startResponse;
2845 p.writeInt32(num);
2846
2847 for (int i = 0 ; i < num ; i++) {
2848 infoRec = &p_cur->infoRec[i];
2849 p.writeInt32(infoRec->name);
2850 switch (infoRec->name) {
2851 case RIL_CDMA_DISPLAY_INFO_REC:
2852 case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
2853 if (infoRec->rec.display.alpha_len >
2854 CDMA_ALPHA_INFO_BUFFER_LENGTH) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002855 RLOGE("invalid display info response length %d \
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002856 expected not more than %d\n",
2857 (int)infoRec->rec.display.alpha_len,
2858 CDMA_ALPHA_INFO_BUFFER_LENGTH);
2859 return RIL_ERRNO_INVALID_RESPONSE;
2860 }
2861 string8 = (char*) malloc((infoRec->rec.display.alpha_len + 1)
2862 * sizeof(char) );
2863 for (int i = 0 ; i < infoRec->rec.display.alpha_len ; i++) {
2864 string8[i] = infoRec->rec.display.alpha_buf[i];
2865 }
2866 string8[(int)infoRec->rec.display.alpha_len] = '\0';
2867 writeStringToParcel(p, (const char*)string8);
2868 free(string8);
2869 string8 = NULL;
2870 break;
2871 case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
2872 case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
2873 case RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
2874 if (infoRec->rec.number.len > CDMA_NUMBER_INFO_BUFFER_LENGTH) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002875 RLOGE("invalid display info response length %d \
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002876 expected not more than %d\n",
2877 (int)infoRec->rec.number.len,
2878 CDMA_NUMBER_INFO_BUFFER_LENGTH);
2879 return RIL_ERRNO_INVALID_RESPONSE;
2880 }
2881 string8 = (char*) malloc((infoRec->rec.number.len + 1)
2882 * sizeof(char) );
2883 for (int i = 0 ; i < infoRec->rec.number.len; i++) {
2884 string8[i] = infoRec->rec.number.buf[i];
2885 }
2886 string8[(int)infoRec->rec.number.len] = '\0';
2887 writeStringToParcel(p, (const char*)string8);
2888 free(string8);
2889 string8 = NULL;
2890 p.writeInt32(infoRec->rec.number.number_type);
2891 p.writeInt32(infoRec->rec.number.number_plan);
2892 p.writeInt32(infoRec->rec.number.pi);
2893 p.writeInt32(infoRec->rec.number.si);
2894 break;
2895 case RIL_CDMA_SIGNAL_INFO_REC:
2896 p.writeInt32(infoRec->rec.signal.isPresent);
2897 p.writeInt32(infoRec->rec.signal.signalType);
2898 p.writeInt32(infoRec->rec.signal.alertPitch);
2899 p.writeInt32(infoRec->rec.signal.signal);
2900
2901 appendPrintBuf("%sisPresent=%X, signalType=%X, \
2902 alertPitch=%X, signal=%X, ",
2903 printBuf, (int)infoRec->rec.signal.isPresent,
2904 (int)infoRec->rec.signal.signalType,
2905 (int)infoRec->rec.signal.alertPitch,
2906 (int)infoRec->rec.signal.signal);
2907 removeLastChar;
2908 break;
2909 case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
2910 if (infoRec->rec.redir.redirectingNumber.len >
2911 CDMA_NUMBER_INFO_BUFFER_LENGTH) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002912 RLOGE("invalid display info response length %d \
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002913 expected not more than %d\n",
2914 (int)infoRec->rec.redir.redirectingNumber.len,
2915 CDMA_NUMBER_INFO_BUFFER_LENGTH);
2916 return RIL_ERRNO_INVALID_RESPONSE;
2917 }
2918 string8 = (char*) malloc((infoRec->rec.redir.redirectingNumber
2919 .len + 1) * sizeof(char) );
2920 for (int i = 0;
2921 i < infoRec->rec.redir.redirectingNumber.len;
2922 i++) {
2923 string8[i] = infoRec->rec.redir.redirectingNumber.buf[i];
2924 }
2925 string8[(int)infoRec->rec.redir.redirectingNumber.len] = '\0';
2926 writeStringToParcel(p, (const char*)string8);
2927 free(string8);
2928 string8 = NULL;
2929 p.writeInt32(infoRec->rec.redir.redirectingNumber.number_type);
2930 p.writeInt32(infoRec->rec.redir.redirectingNumber.number_plan);
2931 p.writeInt32(infoRec->rec.redir.redirectingNumber.pi);
2932 p.writeInt32(infoRec->rec.redir.redirectingNumber.si);
2933 p.writeInt32(infoRec->rec.redir.redirectingReason);
2934 break;
2935 case RIL_CDMA_LINE_CONTROL_INFO_REC:
2936 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPolarityIncluded);
2937 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlToggle);
2938 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlReverse);
2939 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPowerDenial);
2940
2941 appendPrintBuf("%slineCtrlPolarityIncluded=%d, \
2942 lineCtrlToggle=%d, lineCtrlReverse=%d, \
2943 lineCtrlPowerDenial=%d, ", printBuf,
2944 (int)infoRec->rec.lineCtrl.lineCtrlPolarityIncluded,
2945 (int)infoRec->rec.lineCtrl.lineCtrlToggle,
2946 (int)infoRec->rec.lineCtrl.lineCtrlReverse,
2947 (int)infoRec->rec.lineCtrl.lineCtrlPowerDenial);
2948 removeLastChar;
2949 break;
2950 case RIL_CDMA_T53_CLIR_INFO_REC:
2951 p.writeInt32((int)(infoRec->rec.clir.cause));
2952
2953 appendPrintBuf("%scause%d", printBuf, infoRec->rec.clir.cause);
2954 removeLastChar;
2955 break;
2956 case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
2957 p.writeInt32(infoRec->rec.audioCtrl.upLink);
2958 p.writeInt32(infoRec->rec.audioCtrl.downLink);
2959
2960 appendPrintBuf("%supLink=%d, downLink=%d, ", printBuf,
2961 infoRec->rec.audioCtrl.upLink,
2962 infoRec->rec.audioCtrl.downLink);
2963 removeLastChar;
2964 break;
2965 case RIL_CDMA_T53_RELEASE_INFO_REC:
2966 // TODO(Moto): See David Krause, he has the answer:)
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002967 RLOGE("RIL_CDMA_T53_RELEASE_INFO_REC: return INVALID_RESPONSE");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002968 return RIL_ERRNO_INVALID_RESPONSE;
2969 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002970 RLOGE("Incorrect name value");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002971 return RIL_ERRNO_INVALID_RESPONSE;
2972 }
2973 }
2974 closeResponse;
2975
2976 return 0;
2977}
2978
2979static int responseRilSignalStrength(Parcel &p,
2980 void *response, size_t responselen) {
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05302981 int gsmSignalStrength;
2982 int cdmaDbm;
2983 int evdoDbm;
2984
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002985 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002986 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002987 return RIL_ERRNO_INVALID_RESPONSE;
2988 }
2989
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002990 if (responselen >= sizeof (RIL_SignalStrength_v5)) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002991 RIL_SignalStrength_v10 *p_cur = ((RIL_SignalStrength_v10 *) response);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002992
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05302993 gsmSignalStrength = p_cur->GW_SignalStrength.signalStrength & 0xFF;
Utkarsh Gupta8ede9fa2015-04-23 13:21:49 +05302994
2995#ifdef MODEM_TYPE_XMM6260
2996 if (gsmSignalStrength < 0 ||
2997 (gsmSignalStrength > 31 && p_cur->GW_SignalStrength.signalStrength != 99)) {
2998 gsmSignalStrength = p_cur->CDMA_SignalStrength.dbm;
2999 }
3000#else
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303001 if (gsmSignalStrength < 0) {
3002 gsmSignalStrength = 99;
3003 } else if (gsmSignalStrength > 31 && gsmSignalStrength != 99) {
3004 gsmSignalStrength = 31;
3005 }
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303006#endif
3007 p.writeInt32(gsmSignalStrength);
3008
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003009 p.writeInt32(p_cur->GW_SignalStrength.bitErrorRate);
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303010
3011#if defined(MODEM_TYPE_XMM6262) || defined(MODEM_TYPE_XMM7260)
3012 cdmaDbm = p_cur->CDMA_SignalStrength.dbm & 0xFF;
3013 if (cdmaDbm < 0) {
3014 cdmaDbm = 99;
3015 } else if (cdmaDbm > 31 && cdmaDbm != 99) {
3016 cdmaDbm = 31;
3017 }
3018#else
Caio Schnepperec042542015-04-14 08:03:43 -03003019 cdmaDbm = p_cur->CDMA_SignalStrength.dbm;
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303020#endif
3021 p.writeInt32(cdmaDbm);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003022 p.writeInt32(p_cur->CDMA_SignalStrength.ecio);
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303023
3024#if defined(MODEM_TYPE_XMM6262) || defined(MODEM_TYPE_XMM7260)
3025 evdoDbm = p_cur->EVDO_SignalStrength.dbm & 0xFF;
3026 if (evdoDbm < 0) {
3027 evdoDbm = 99;
3028 } else if (evdoDbm > 31 && evdoDbm != 99) {
3029 evdoDbm = 31;
3030 }
3031#else
3032 evdoDbm = p_cur->EVDO_SignalStrength.dbm;
3033#endif
3034 p.writeInt32(evdoDbm);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003035 p.writeInt32(p_cur->EVDO_SignalStrength.ecio);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003036 p.writeInt32(p_cur->EVDO_SignalStrength.signalNoiseRatio);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003037 if (responselen >= sizeof (RIL_SignalStrength_v6)) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003038 /*
Ethan Chend6e30652013-08-04 22:49:56 -07003039 * Fixup LTE for backwards compatibility
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003040 */
Ethan Chend6e30652013-08-04 22:49:56 -07003041 if (s_callbacks.version <= 6) {
3042 // signalStrength: -1 -> 99
3043 if (p_cur->LTE_SignalStrength.signalStrength == -1) {
3044 p_cur->LTE_SignalStrength.signalStrength = 99;
3045 }
3046 // rsrp: -1 -> INT_MAX all other negative value to positive.
3047 // So remap here
3048 if (p_cur->LTE_SignalStrength.rsrp == -1) {
3049 p_cur->LTE_SignalStrength.rsrp = INT_MAX;
3050 } else if (p_cur->LTE_SignalStrength.rsrp < -1) {
3051 p_cur->LTE_SignalStrength.rsrp = -p_cur->LTE_SignalStrength.rsrp;
3052 }
3053 // rsrq: -1 -> INT_MAX
3054 if (p_cur->LTE_SignalStrength.rsrq == -1) {
3055 p_cur->LTE_SignalStrength.rsrq = INT_MAX;
3056 }
3057 // Not remapping rssnr is already using INT_MAX
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003058
Ethan Chend6e30652013-08-04 22:49:56 -07003059 // cqi: -1 -> INT_MAX
3060 if (p_cur->LTE_SignalStrength.cqi == -1) {
3061 p_cur->LTE_SignalStrength.cqi = INT_MAX;
3062 }
3063 }
3064 p.writeInt32(p_cur->LTE_SignalStrength.signalStrength);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003065 p.writeInt32(p_cur->LTE_SignalStrength.rsrp);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003066 p.writeInt32(p_cur->LTE_SignalStrength.rsrq);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003067 p.writeInt32(p_cur->LTE_SignalStrength.rssnr);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003068 p.writeInt32(p_cur->LTE_SignalStrength.cqi);
Howard Sue32dbfd2015-01-07 15:55:57 +08003069 if (responselen >= sizeof (RIL_SignalStrength_v10)) {
3070 p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp);
3071 } else {
3072 p.writeInt32(INT_MAX);
3073 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003074 } else {
Ethan Chend6e30652013-08-04 22:49:56 -07003075 p.writeInt32(99);
3076 p.writeInt32(INT_MAX);
3077 p.writeInt32(INT_MAX);
3078 p.writeInt32(INT_MAX);
3079 p.writeInt32(INT_MAX);
Howard Sue32dbfd2015-01-07 15:55:57 +08003080 p.writeInt32(INT_MAX);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003081 }
3082
3083 startResponse;
3084 appendPrintBuf("%s[signalStrength=%d,bitErrorRate=%d,\
3085 CDMA_SS.dbm=%d,CDMA_SSecio=%d,\
3086 EVDO_SS.dbm=%d,EVDO_SS.ecio=%d,\
3087 EVDO_SS.signalNoiseRatio=%d,\
3088 LTE_SS.signalStrength=%d,LTE_SS.rsrp=%d,LTE_SS.rsrq=%d,\
Howard Sue32dbfd2015-01-07 15:55:57 +08003089 LTE_SS.rssnr=%d,LTE_SS.cqi=%d,TDSCDMA_SS.rscp=%d]",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003090 printBuf,
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303091 gsmSignalStrength,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003092 p_cur->GW_SignalStrength.bitErrorRate,
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303093 cdmaDbm,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003094 p_cur->CDMA_SignalStrength.ecio,
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303095 evdoDbm,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003096 p_cur->EVDO_SignalStrength.ecio,
3097 p_cur->EVDO_SignalStrength.signalNoiseRatio,
3098 p_cur->LTE_SignalStrength.signalStrength,
3099 p_cur->LTE_SignalStrength.rsrp,
3100 p_cur->LTE_SignalStrength.rsrq,
3101 p_cur->LTE_SignalStrength.rssnr,
Howard Sue32dbfd2015-01-07 15:55:57 +08003102 p_cur->LTE_SignalStrength.cqi,
3103 p_cur->TD_SCDMA_SignalStrength.rscp);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003104 closeResponse;
3105
3106 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003107 RLOGE("invalid response length");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003108 return RIL_ERRNO_INVALID_RESPONSE;
3109 }
3110
3111 return 0;
3112}
3113
3114static int responseCallRing(Parcel &p, void *response, size_t responselen) {
3115 if ((response == NULL) || (responselen == 0)) {
3116 return responseVoid(p, response, responselen);
3117 } else {
3118 return responseCdmaSignalInfoRecord(p, response, responselen);
3119 }
3120}
3121
3122static int responseCdmaSignalInfoRecord(Parcel &p, void *response, size_t responselen) {
3123 if (response == NULL || responselen == 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003124 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003125 return RIL_ERRNO_INVALID_RESPONSE;
3126 }
3127
3128 if (responselen != sizeof (RIL_CDMA_SignalInfoRecord)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003129 RLOGE("invalid response length %d expected sizeof (RIL_CDMA_SignalInfoRecord) of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003130 (int)responselen, (int)sizeof (RIL_CDMA_SignalInfoRecord));
3131 return RIL_ERRNO_INVALID_RESPONSE;
3132 }
3133
3134 startResponse;
3135
3136 RIL_CDMA_SignalInfoRecord *p_cur = ((RIL_CDMA_SignalInfoRecord *) response);
3137 marshallSignalInfoRecord(p, *p_cur);
3138
3139 appendPrintBuf("%s[isPresent=%d,signalType=%d,alertPitch=%d\
3140 signal=%d]",
3141 printBuf,
3142 p_cur->isPresent,
3143 p_cur->signalType,
3144 p_cur->alertPitch,
3145 p_cur->signal);
3146
3147 closeResponse;
3148 return 0;
3149}
3150
3151static int responseCdmaCallWaiting(Parcel &p, void *response,
3152 size_t responselen) {
3153 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003154 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003155 return RIL_ERRNO_INVALID_RESPONSE;
3156 }
3157
3158 if (responselen < sizeof(RIL_CDMA_CallWaiting_v6)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003159 RLOGW("Upgrade to ril version %d\n", RIL_VERSION);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003160 }
3161
3162 RIL_CDMA_CallWaiting_v6 *p_cur = ((RIL_CDMA_CallWaiting_v6 *) response);
3163
3164 writeStringToParcel(p, p_cur->number);
3165 p.writeInt32(p_cur->numberPresentation);
3166 writeStringToParcel(p, p_cur->name);
3167 marshallSignalInfoRecord(p, p_cur->signalInfoRecord);
3168
3169 if (responselen >= sizeof(RIL_CDMA_CallWaiting_v6)) {
3170 p.writeInt32(p_cur->number_type);
3171 p.writeInt32(p_cur->number_plan);
3172 } else {
3173 p.writeInt32(0);
3174 p.writeInt32(0);
3175 }
3176
3177 startResponse;
3178 appendPrintBuf("%snumber=%s,numberPresentation=%d, name=%s,\
3179 signalInfoRecord[isPresent=%d,signalType=%d,alertPitch=%d\
3180 signal=%d,number_type=%d,number_plan=%d]",
3181 printBuf,
3182 p_cur->number,
3183 p_cur->numberPresentation,
3184 p_cur->name,
3185 p_cur->signalInfoRecord.isPresent,
3186 p_cur->signalInfoRecord.signalType,
3187 p_cur->signalInfoRecord.alertPitch,
3188 p_cur->signalInfoRecord.signal,
3189 p_cur->number_type,
3190 p_cur->number_plan);
3191 closeResponse;
3192
3193 return 0;
3194}
3195
3196static int responseSimRefresh(Parcel &p, void *response, size_t responselen) {
3197 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003198 RLOGE("responseSimRefresh: invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003199 return RIL_ERRNO_INVALID_RESPONSE;
3200 }
3201
3202 startResponse;
3203 if (s_callbacks.version == 7) {
3204 RIL_SimRefreshResponse_v7 *p_cur = ((RIL_SimRefreshResponse_v7 *) response);
3205 p.writeInt32(p_cur->result);
3206 p.writeInt32(p_cur->ef_id);
3207 writeStringToParcel(p, p_cur->aid);
3208
3209 appendPrintBuf("%sresult=%d, ef_id=%d, aid=%s",
3210 printBuf,
3211 p_cur->result,
3212 p_cur->ef_id,
3213 p_cur->aid);
3214 } else {
3215 int *p_cur = ((int *) response);
3216 p.writeInt32(p_cur[0]);
3217 p.writeInt32(p_cur[1]);
3218 writeStringToParcel(p, NULL);
3219
3220 appendPrintBuf("%sresult=%d, ef_id=%d",
3221 printBuf,
3222 p_cur[0],
3223 p_cur[1]);
3224 }
3225 closeResponse;
3226
3227 return 0;
3228}
3229
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003230static int responseCellInfoList(Parcel &p, void *response, size_t responselen)
3231{
3232 if (response == NULL && responselen != 0) {
3233 RLOGE("invalid response: NULL");
3234 return RIL_ERRNO_INVALID_RESPONSE;
3235 }
3236
3237 if (responselen % sizeof(RIL_CellInfo) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08003238 RLOGE("responseCellInfoList: invalid response length %d expected multiple of %d",
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003239 (int)responselen, (int)sizeof(RIL_CellInfo));
3240 return RIL_ERRNO_INVALID_RESPONSE;
3241 }
3242
3243 int num = responselen / sizeof(RIL_CellInfo);
3244 p.writeInt32(num);
3245
3246 RIL_CellInfo *p_cur = (RIL_CellInfo *) response;
3247 startResponse;
3248 int i;
3249 for (i = 0; i < num; i++) {
3250 appendPrintBuf("%s[%d: type=%d,registered=%d,timeStampType=%d,timeStamp=%lld", printBuf, i,
3251 p_cur->cellInfoType, p_cur->registered, p_cur->timeStampType, p_cur->timeStamp);
3252 p.writeInt32((int)p_cur->cellInfoType);
3253 p.writeInt32(p_cur->registered);
3254 p.writeInt32(p_cur->timeStampType);
3255 p.writeInt64(p_cur->timeStamp);
3256 switch(p_cur->cellInfoType) {
3257 case RIL_CELL_INFO_TYPE_GSM: {
3258 appendPrintBuf("%s GSM id: mcc=%d,mnc=%d,lac=%d,cid=%d,", printBuf,
3259 p_cur->CellInfo.gsm.cellIdentityGsm.mcc,
3260 p_cur->CellInfo.gsm.cellIdentityGsm.mnc,
3261 p_cur->CellInfo.gsm.cellIdentityGsm.lac,
3262 p_cur->CellInfo.gsm.cellIdentityGsm.cid);
3263 appendPrintBuf("%s gsmSS: ss=%d,ber=%d],", printBuf,
3264 p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength,
3265 p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
3266
3267 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mcc);
3268 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mnc);
3269 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.lac);
3270 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.cid);
3271 p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength);
3272 p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
3273 break;
3274 }
3275 case RIL_CELL_INFO_TYPE_WCDMA: {
3276 appendPrintBuf("%s WCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,psc=%d,", printBuf,
3277 p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc,
3278 p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc,
3279 p_cur->CellInfo.wcdma.cellIdentityWcdma.lac,
3280 p_cur->CellInfo.wcdma.cellIdentityWcdma.cid,
3281 p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
3282 appendPrintBuf("%s wcdmaSS: ss=%d,ber=%d],", printBuf,
3283 p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength,
3284 p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
3285
3286 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc);
3287 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc);
3288 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.lac);
3289 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.cid);
3290 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
3291 p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength);
3292 p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
3293 break;
3294 }
3295 case RIL_CELL_INFO_TYPE_CDMA: {
3296 appendPrintBuf("%s CDMA id: nId=%d,sId=%d,bsId=%d,long=%d,lat=%d", printBuf,
3297 p_cur->CellInfo.cdma.cellIdentityCdma.networkId,
3298 p_cur->CellInfo.cdma.cellIdentityCdma.systemId,
3299 p_cur->CellInfo.cdma.cellIdentityCdma.basestationId,
3300 p_cur->CellInfo.cdma.cellIdentityCdma.longitude,
3301 p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
3302
3303 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.networkId);
3304 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.systemId);
3305 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.basestationId);
3306 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.longitude);
3307 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
3308
3309 appendPrintBuf("%s cdmaSS: dbm=%d ecio=%d evdoSS: dbm=%d,ecio=%d,snr=%d", printBuf,
3310 p_cur->CellInfo.cdma.signalStrengthCdma.dbm,
3311 p_cur->CellInfo.cdma.signalStrengthCdma.ecio,
3312 p_cur->CellInfo.cdma.signalStrengthEvdo.dbm,
3313 p_cur->CellInfo.cdma.signalStrengthEvdo.ecio,
3314 p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
3315
3316 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.dbm);
3317 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.ecio);
3318 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.dbm);
3319 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.ecio);
3320 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
3321 break;
3322 }
3323 case RIL_CELL_INFO_TYPE_LTE: {
3324 appendPrintBuf("%s LTE id: mcc=%d,mnc=%d,ci=%d,pci=%d,tac=%d", printBuf,
3325 p_cur->CellInfo.lte.cellIdentityLte.mcc,
3326 p_cur->CellInfo.lte.cellIdentityLte.mnc,
3327 p_cur->CellInfo.lte.cellIdentityLte.ci,
3328 p_cur->CellInfo.lte.cellIdentityLte.pci,
3329 p_cur->CellInfo.lte.cellIdentityLte.tac);
3330
3331 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mcc);
3332 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mnc);
3333 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.ci);
3334 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.pci);
3335 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.tac);
3336
3337 appendPrintBuf("%s lteSS: ss=%d,rsrp=%d,rsrq=%d,rssnr=%d,cqi=%d,ta=%d", printBuf,
3338 p_cur->CellInfo.lte.signalStrengthLte.signalStrength,
3339 p_cur->CellInfo.lte.signalStrengthLte.rsrp,
3340 p_cur->CellInfo.lte.signalStrengthLte.rsrq,
3341 p_cur->CellInfo.lte.signalStrengthLte.rssnr,
3342 p_cur->CellInfo.lte.signalStrengthLte.cqi,
3343 p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
3344 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.signalStrength);
3345 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrp);
3346 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrq);
3347 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rssnr);
3348 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.cqi);
3349 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
3350 break;
3351 }
Howard Sue32dbfd2015-01-07 15:55:57 +08003352 case RIL_CELL_INFO_TYPE_TD_SCDMA: {
3353 appendPrintBuf("%s TDSCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,cpid=%d,", printBuf,
3354 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc,
3355 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc,
3356 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac,
3357 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid,
3358 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid);
3359 appendPrintBuf("%s tdscdmaSS: rscp=%d],", printBuf,
3360 p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp);
3361
3362 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc);
3363 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc);
3364 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac);
3365 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid);
3366 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid);
3367 p.writeInt32(p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp);
3368 break;
3369 }
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003370 }
3371 p_cur += 1;
3372 }
3373 removeLastChar;
3374 closeResponse;
3375
3376 return 0;
3377}
3378
Howard Sue32dbfd2015-01-07 15:55:57 +08003379static int responseHardwareConfig(Parcel &p, void *response, size_t responselen)
3380{
3381 if (response == NULL && responselen != 0) {
3382 RLOGE("invalid response: NULL");
3383 return RIL_ERRNO_INVALID_RESPONSE;
3384 }
3385
3386 if (responselen % sizeof(RIL_HardwareConfig) != 0) {
3387 RLOGE("responseHardwareConfig: invalid response length %d expected multiple of %d",
3388 (int)responselen, (int)sizeof(RIL_HardwareConfig));
3389 return RIL_ERRNO_INVALID_RESPONSE;
3390 }
3391
3392 int num = responselen / sizeof(RIL_HardwareConfig);
3393 int i;
3394 RIL_HardwareConfig *p_cur = (RIL_HardwareConfig *) response;
3395
3396 p.writeInt32(num);
3397
3398 startResponse;
3399 for (i = 0; i < num; i++) {
3400 switch (p_cur[i].type) {
3401 case RIL_HARDWARE_CONFIG_MODEM: {
3402 writeStringToParcel(p, p_cur[i].uuid);
3403 p.writeInt32((int)p_cur[i].state);
3404 p.writeInt32(p_cur[i].cfg.modem.rat);
3405 p.writeInt32(p_cur[i].cfg.modem.maxVoice);
3406 p.writeInt32(p_cur[i].cfg.modem.maxData);
3407 p.writeInt32(p_cur[i].cfg.modem.maxStandby);
3408
3409 appendPrintBuf("%s modem: uuid=%s,state=%d,rat=%08x,maxV=%d,maxD=%d,maxS=%d", printBuf,
3410 p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.modem.rat,
3411 p_cur[i].cfg.modem.maxVoice, p_cur[i].cfg.modem.maxData, p_cur[i].cfg.modem.maxStandby);
3412 break;
3413 }
3414 case RIL_HARDWARE_CONFIG_SIM: {
3415 writeStringToParcel(p, p_cur[i].uuid);
3416 p.writeInt32((int)p_cur[i].state);
3417 writeStringToParcel(p, p_cur[i].cfg.sim.modemUuid);
3418
3419 appendPrintBuf("%s sim: uuid=%s,state=%d,modem-uuid=%s", printBuf,
3420 p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.sim.modemUuid);
3421 break;
3422 }
3423 }
3424 }
3425 removeLastChar;
3426 closeResponse;
3427 return 0;
3428}
3429
Howard Subd82ef12015-04-12 10:25:05 +02003430static int responseRadioCapability(Parcel &p, void *response, size_t responselen) {
3431 if (response == NULL) {
3432 RLOGE("invalid response: NULL");
3433 return RIL_ERRNO_INVALID_RESPONSE;
3434 }
3435
3436 if (responselen != sizeof (RIL_RadioCapability) ) {
3437 RLOGE("invalid response length was %d expected %d",
3438 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
3439 return RIL_ERRNO_INVALID_RESPONSE;
3440 }
3441
3442 RIL_RadioCapability *p_cur = (RIL_RadioCapability *) response;
3443 p.writeInt32(p_cur->version);
3444 p.writeInt32(p_cur->session);
3445 p.writeInt32(p_cur->phase);
3446 p.writeInt32(p_cur->rat);
3447 writeStringToParcel(p, p_cur->logicalModemUuid);
3448 p.writeInt32(p_cur->status);
3449
3450 startResponse;
3451 appendPrintBuf("%s[version=%d,session=%d,phase=%d,\
3452 rat=%s,logicalModemUuid=%s,status=%d]",
3453 printBuf,
3454 p_cur->version,
3455 p_cur->session,
3456 p_cur->phase,
3457 p_cur->rat,
3458 p_cur->logicalModemUuid,
3459 p_cur->status);
3460 closeResponse;
3461 return 0;
3462}
3463
3464static int responseSSData(Parcel &p, void *response, size_t responselen) {
3465 RLOGD("In responseSSData");
3466 int num;
3467
3468 if (response == NULL && responselen != 0) {
3469 RLOGE("invalid response length was %d expected %d",
3470 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
3471 return RIL_ERRNO_INVALID_RESPONSE;
3472 }
3473
3474 if (responselen != sizeof(RIL_StkCcUnsolSsResponse)) {
3475 RLOGE("invalid response length %d, expected %d",
3476 (int)responselen, (int)sizeof(RIL_StkCcUnsolSsResponse));
3477 return RIL_ERRNO_INVALID_RESPONSE;
3478 }
3479
3480 startResponse;
3481 RIL_StkCcUnsolSsResponse *p_cur = (RIL_StkCcUnsolSsResponse *) response;
3482 p.writeInt32(p_cur->serviceType);
3483 p.writeInt32(p_cur->requestType);
3484 p.writeInt32(p_cur->teleserviceType);
3485 p.writeInt32(p_cur->serviceClass);
3486 p.writeInt32(p_cur->result);
3487
3488 if (isServiceTypeCfQuery(p_cur->serviceType, p_cur->requestType)) {
3489 RLOGD("responseSSData CF type, num of Cf elements %d", p_cur->cfData.numValidIndexes);
3490 if (p_cur->cfData.numValidIndexes > NUM_SERVICE_CLASSES) {
3491 RLOGE("numValidIndexes is greater than max value %d, "
3492 "truncating it to max value", NUM_SERVICE_CLASSES);
3493 p_cur->cfData.numValidIndexes = NUM_SERVICE_CLASSES;
3494 }
3495 /* number of call info's */
3496 p.writeInt32(p_cur->cfData.numValidIndexes);
3497
3498 for (int i = 0; i < p_cur->cfData.numValidIndexes; i++) {
3499 RIL_CallForwardInfo cf = p_cur->cfData.cfInfo[i];
3500
3501 p.writeInt32(cf.status);
3502 p.writeInt32(cf.reason);
3503 p.writeInt32(cf.serviceClass);
3504 p.writeInt32(cf.toa);
3505 writeStringToParcel(p, cf.number);
3506 p.writeInt32(cf.timeSeconds);
3507 appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
3508 (cf.status==1)?"enable":"disable", cf.reason, cf.serviceClass, cf.toa,
3509 (char*)cf.number, cf.timeSeconds);
3510 RLOGD("Data: %d,reason=%d,cls=%d,toa=%d,num=%s,tout=%d],", cf.status,
3511 cf.reason, cf.serviceClass, cf.toa, (char*)cf.number, cf.timeSeconds);
3512 }
3513 } else {
3514 p.writeInt32 (SS_INFO_MAX);
3515
3516 /* each int*/
3517 for (int i = 0; i < SS_INFO_MAX; i++) {
3518 appendPrintBuf("%s%d,", printBuf, p_cur->ssInfo[i]);
3519 RLOGD("Data: %d",p_cur->ssInfo[i]);
3520 p.writeInt32(p_cur->ssInfo[i]);
3521 }
3522 }
3523 removeLastChar;
3524 closeResponse;
3525
3526 return 0;
3527}
3528
3529static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType) {
3530 if ((reqType == SS_INTERROGATION) &&
3531 (serType == SS_CFU ||
3532 serType == SS_CF_BUSY ||
3533 serType == SS_CF_NO_REPLY ||
3534 serType == SS_CF_NOT_REACHABLE ||
3535 serType == SS_CF_ALL ||
3536 serType == SS_CF_ALL_CONDITIONAL)) {
3537 return true;
3538 }
3539 return false;
3540}
3541
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003542static void triggerEvLoop() {
3543 int ret;
3544 if (!pthread_equal(pthread_self(), s_tid_dispatch)) {
3545 /* trigger event loop to wakeup. No reason to do this,
3546 * if we're in the event loop thread */
3547 do {
3548 ret = write (s_fdWakeupWrite, " ", 1);
3549 } while (ret < 0 && errno == EINTR);
3550 }
3551}
3552
3553static void rilEventAddWakeup(struct ril_event *ev) {
3554 ril_event_add(ev);
3555 triggerEvLoop();
3556}
3557
3558static void sendSimStatusAppInfo(Parcel &p, int num_apps, RIL_AppStatus appStatus[]) {
3559 p.writeInt32(num_apps);
3560 startResponse;
3561 for (int i = 0; i < num_apps; i++) {
3562 p.writeInt32(appStatus[i].app_type);
3563 p.writeInt32(appStatus[i].app_state);
3564 p.writeInt32(appStatus[i].perso_substate);
3565 writeStringToParcel(p, (const char*)(appStatus[i].aid_ptr));
3566 writeStringToParcel(p, (const char*)
3567 (appStatus[i].app_label_ptr));
3568 p.writeInt32(appStatus[i].pin1_replaced);
3569 p.writeInt32(appStatus[i].pin1);
3570 p.writeInt32(appStatus[i].pin2);
3571 appendPrintBuf("%s[app_type=%d,app_state=%d,perso_substate=%d,\
3572 aid_ptr=%s,app_label_ptr=%s,pin1_replaced=%d,pin1=%d,pin2=%d],",
3573 printBuf,
3574 appStatus[i].app_type,
3575 appStatus[i].app_state,
3576 appStatus[i].perso_substate,
3577 appStatus[i].aid_ptr,
3578 appStatus[i].app_label_ptr,
3579 appStatus[i].pin1_replaced,
3580 appStatus[i].pin1,
3581 appStatus[i].pin2);
3582 }
3583 closeResponse;
3584}
3585
3586static int responseSimStatus(Parcel &p, void *response, size_t responselen) {
Howard Sue32dbfd2015-01-07 15:55:57 +08003587 int i;
3588
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003589 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003590 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003591 return RIL_ERRNO_INVALID_RESPONSE;
3592 }
3593
3594 if (responselen == sizeof (RIL_CardStatus_v6)) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003595 RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
3596
3597 p.writeInt32(p_cur->card_state);
3598 p.writeInt32(p_cur->universal_pin_state);
3599 p.writeInt32(p_cur->gsm_umts_subscription_app_index);
3600 p.writeInt32(p_cur->cdma_subscription_app_index);
3601 p.writeInt32(p_cur->ims_subscription_app_index);
3602
3603 sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
3604 } else if (responselen == sizeof (RIL_CardStatus_v5)) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003605 RIL_CardStatus_v5 *p_cur = ((RIL_CardStatus_v5 *) response);
3606
3607 p.writeInt32(p_cur->card_state);
3608 p.writeInt32(p_cur->universal_pin_state);
3609 p.writeInt32(p_cur->gsm_umts_subscription_app_index);
3610 p.writeInt32(p_cur->cdma_subscription_app_index);
3611 p.writeInt32(-1);
3612
3613 sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
3614 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003615 RLOGE("responseSimStatus: A RilCardStatus_v6 or _v5 expected\n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003616 return RIL_ERRNO_INVALID_RESPONSE;
3617 }
3618
3619 return 0;
3620}
3621
3622static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen) {
3623 int num = responselen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *);
3624 p.writeInt32(num);
3625
3626 startResponse;
3627 RIL_GSM_BroadcastSmsConfigInfo **p_cur =
3628 (RIL_GSM_BroadcastSmsConfigInfo **) response;
3629 for (int i = 0; i < num; i++) {
3630 p.writeInt32(p_cur[i]->fromServiceId);
3631 p.writeInt32(p_cur[i]->toServiceId);
3632 p.writeInt32(p_cur[i]->fromCodeScheme);
3633 p.writeInt32(p_cur[i]->toCodeScheme);
3634 p.writeInt32(p_cur[i]->selected);
3635
3636 appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId=%d, \
3637 fromCodeScheme=%d, toCodeScheme=%d, selected =%d]",
3638 printBuf, i, p_cur[i]->fromServiceId, p_cur[i]->toServiceId,
3639 p_cur[i]->fromCodeScheme, p_cur[i]->toCodeScheme,
3640 p_cur[i]->selected);
3641 }
3642 closeResponse;
3643
3644 return 0;
3645}
3646
3647static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen) {
3648 RIL_CDMA_BroadcastSmsConfigInfo **p_cur =
3649 (RIL_CDMA_BroadcastSmsConfigInfo **) response;
3650
3651 int num = responselen / sizeof (RIL_CDMA_BroadcastSmsConfigInfo *);
3652 p.writeInt32(num);
3653
3654 startResponse;
3655 for (int i = 0 ; i < num ; i++ ) {
3656 p.writeInt32(p_cur[i]->service_category);
3657 p.writeInt32(p_cur[i]->language);
3658 p.writeInt32(p_cur[i]->selected);
3659
3660 appendPrintBuf("%s [%d: srvice_category=%d, language =%d, \
3661 selected =%d], ",
3662 printBuf, i, p_cur[i]->service_category, p_cur[i]->language,
3663 p_cur[i]->selected);
3664 }
3665 closeResponse;
3666
3667 return 0;
3668}
3669
3670static int responseCdmaSms(Parcel &p, void *response, size_t responselen) {
3671 int num;
3672 int digitCount;
3673 int digitLimit;
3674 uint8_t uct;
3675 void* dest;
3676
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003677 RLOGD("Inside responseCdmaSms");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003678
3679 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003680 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003681 return RIL_ERRNO_INVALID_RESPONSE;
3682 }
3683
3684 if (responselen != sizeof(RIL_CDMA_SMS_Message)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003685 RLOGE("invalid response length was %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003686 (int)responselen, (int)sizeof(RIL_CDMA_SMS_Message));
3687 return RIL_ERRNO_INVALID_RESPONSE;
3688 }
3689
3690 RIL_CDMA_SMS_Message *p_cur = (RIL_CDMA_SMS_Message *) response;
3691 p.writeInt32(p_cur->uTeleserviceID);
3692 p.write(&(p_cur->bIsServicePresent),sizeof(uct));
3693 p.writeInt32(p_cur->uServicecategory);
3694 p.writeInt32(p_cur->sAddress.digit_mode);
3695 p.writeInt32(p_cur->sAddress.number_mode);
3696 p.writeInt32(p_cur->sAddress.number_type);
3697 p.writeInt32(p_cur->sAddress.number_plan);
3698 p.write(&(p_cur->sAddress.number_of_digits), sizeof(uct));
3699 digitLimit= MIN((p_cur->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
3700 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
3701 p.write(&(p_cur->sAddress.digits[digitCount]),sizeof(uct));
3702 }
3703
3704 p.writeInt32(p_cur->sSubAddress.subaddressType);
3705 p.write(&(p_cur->sSubAddress.odd),sizeof(uct));
3706 p.write(&(p_cur->sSubAddress.number_of_digits),sizeof(uct));
3707 digitLimit= MIN((p_cur->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
3708 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
3709 p.write(&(p_cur->sSubAddress.digits[digitCount]),sizeof(uct));
3710 }
3711
3712 digitLimit= MIN((p_cur->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
3713 p.writeInt32(p_cur->uBearerDataLen);
3714 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
3715 p.write(&(p_cur->aBearerData[digitCount]), sizeof(uct));
3716 }
3717
3718 startResponse;
3719 appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
3720 sAddress.digit_mode=%d, sAddress.number_mode=%d, sAddress.number_type=%d, ",
3721 printBuf, p_cur->uTeleserviceID,p_cur->bIsServicePresent,p_cur->uServicecategory,
3722 p_cur->sAddress.digit_mode, p_cur->sAddress.number_mode,p_cur->sAddress.number_type);
3723 closeResponse;
3724
3725 return 0;
3726}
3727
Howard Sue32dbfd2015-01-07 15:55:57 +08003728static int responseDcRtInfo(Parcel &p, void *response, size_t responselen)
3729{
3730 int num = responselen / sizeof(RIL_DcRtInfo);
3731 if ((responselen % sizeof(RIL_DcRtInfo) != 0) || (num != 1)) {
3732 RLOGE("responseDcRtInfo: invalid response length %d expected multiple of %d",
3733 (int)responselen, (int)sizeof(RIL_DcRtInfo));
3734 return RIL_ERRNO_INVALID_RESPONSE;
3735 }
3736
3737 startResponse;
3738 RIL_DcRtInfo *pDcRtInfo = (RIL_DcRtInfo *)response;
3739 p.writeInt64(pDcRtInfo->time);
3740 p.writeInt32(pDcRtInfo->powerState);
3741 appendPrintBuf("%s[time=%d,powerState=%d]", printBuf,
3742 pDcRtInfo->time,
3743 pDcRtInfo->powerState);
3744 closeResponse;
3745
3746 return 0;
3747}
3748
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003749/**
3750 * A write on the wakeup fd is done just to pop us out of select()
3751 * We empty the buffer here and then ril_event will reset the timers on the
3752 * way back down
3753 */
3754static void processWakeupCallback(int fd, short flags, void *param) {
3755 char buff[16];
3756 int ret;
3757
Ethan Chend6e30652013-08-04 22:49:56 -07003758 RLOGV("processWakeupCallback");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003759
3760 /* empty our wakeup socket out */
3761 do {
3762 ret = read(s_fdWakeupRead, &buff, sizeof(buff));
3763 } while (ret > 0 || (ret < 0 && errno == EINTR));
3764}
3765
Howard Sue32dbfd2015-01-07 15:55:57 +08003766static void onCommandsSocketClosed(RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003767 int ret;
3768 RequestInfo *p_cur;
Howard Sue32dbfd2015-01-07 15:55:57 +08003769 /* Hook for current context
3770 pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
3771 pthread_mutex_t * pendingRequestsMutexHook = &s_pendingRequestsMutex;
3772 /* pendingRequestsHook refer to &s_pendingRequests */
3773 RequestInfo ** pendingRequestsHook = &s_pendingRequests;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003774
Howard Sue32dbfd2015-01-07 15:55:57 +08003775#if (SIM_COUNT >= 2)
3776 if (socket_id == RIL_SOCKET_2) {
3777 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
3778 pendingRequestsHook = &s_pendingRequests_socket2;
3779 }
3780#if (SIM_COUNT >= 3)
3781 else if (socket_id == RIL_SOCKET_3) {
3782 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
3783 pendingRequestsHook = &s_pendingRequests_socket3;
3784 }
3785#endif
3786#if (SIM_COUNT >= 4)
3787 else if (socket_id == RIL_SOCKET_4) {
3788 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
3789 pendingRequestsHook = &s_pendingRequests_socket4;
3790 }
3791#endif
3792#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003793 /* mark pending requests as "cancelled" so we dont report responses */
Howard Sue32dbfd2015-01-07 15:55:57 +08003794 ret = pthread_mutex_lock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003795 assert (ret == 0);
3796
Howard Sue32dbfd2015-01-07 15:55:57 +08003797 p_cur = *pendingRequestsHook;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003798
Howard Sue32dbfd2015-01-07 15:55:57 +08003799 for (p_cur = *pendingRequestsHook
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003800 ; p_cur != NULL
3801 ; p_cur = p_cur->p_next
3802 ) {
3803 p_cur->cancelled = 1;
3804 }
3805
Howard Sue32dbfd2015-01-07 15:55:57 +08003806 ret = pthread_mutex_unlock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003807 assert (ret == 0);
3808}
3809
3810static void processCommandsCallback(int fd, short flags, void *param) {
3811 RecordStream *p_rs;
3812 void *p_record;
3813 size_t recordlen;
3814 int ret;
Howard Sue32dbfd2015-01-07 15:55:57 +08003815 SocketListenParam *p_info = (SocketListenParam *)param;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003816
Howard Sue32dbfd2015-01-07 15:55:57 +08003817 assert(fd == p_info->fdCommand);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003818
Howard Sue32dbfd2015-01-07 15:55:57 +08003819 p_rs = p_info->p_rs;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003820
3821 for (;;) {
3822 /* loop until EAGAIN/EINTR, end of stream, or other error */
3823 ret = record_stream_get_next(p_rs, &p_record, &recordlen);
3824
3825 if (ret == 0 && p_record == NULL) {
3826 /* end-of-stream */
3827 break;
3828 } else if (ret < 0) {
3829 break;
3830 } else if (ret == 0) { /* && p_record != NULL */
Howard Sue32dbfd2015-01-07 15:55:57 +08003831 processCommandBuffer(p_record, recordlen, p_info->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003832 }
3833 }
3834
3835 if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) {
3836 /* fatal error or end-of-stream */
3837 if (ret != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003838 RLOGE("error on reading command socket errno:%d\n", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003839 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003840 RLOGW("EOS. Closing command socket.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003841 }
3842
Howard Sue32dbfd2015-01-07 15:55:57 +08003843 close(fd);
3844 p_info->fdCommand = -1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003845
Howard Sue32dbfd2015-01-07 15:55:57 +08003846 ril_event_del(p_info->commands_event);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003847
3848 record_stream_free(p_rs);
3849
3850 /* start listening for new connections again */
3851 rilEventAddWakeup(&s_listen_event);
3852
Howard Sue32dbfd2015-01-07 15:55:57 +08003853 onCommandsSocketClosed(p_info->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003854 }
3855}
3856
Howard Subd82ef12015-04-12 10:25:05 +02003857
Howard Sue32dbfd2015-01-07 15:55:57 +08003858static void onNewCommandConnect(RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003859 // Inform we are connected and the ril version
3860 int rilVer = s_callbacks.version;
Howard Sue32dbfd2015-01-07 15:55:57 +08003861 RIL_UNSOL_RESPONSE(RIL_UNSOL_RIL_CONNECTED,
3862 &rilVer, sizeof(rilVer), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003863
3864 // implicit radio state changed
Howard Sue32dbfd2015-01-07 15:55:57 +08003865 RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
3866 NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003867
3868 // Send last NITZ time data, in case it was missed
3869 if (s_lastNITZTimeData != NULL) {
Howard Sue32dbfd2015-01-07 15:55:57 +08003870 sendResponseRaw(s_lastNITZTimeData, s_lastNITZTimeDataSize, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003871
3872 free(s_lastNITZTimeData);
3873 s_lastNITZTimeData = NULL;
3874 }
3875
3876 // Get version string
3877 if (s_callbacks.getVersion != NULL) {
3878 const char *version;
3879 version = s_callbacks.getVersion();
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003880 RLOGI("RIL Daemon version: %s\n", version);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003881
3882 property_set(PROPERTY_RIL_IMPL, version);
3883 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003884 RLOGI("RIL Daemon version: unavailable\n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003885 property_set(PROPERTY_RIL_IMPL, "unavailable");
3886 }
3887
3888}
3889
3890static void listenCallback (int fd, short flags, void *param) {
3891 int ret;
3892 int err;
3893 int is_phone_socket;
Howard Sue32dbfd2015-01-07 15:55:57 +08003894 int fdCommand = -1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003895 RecordStream *p_rs;
Howard Sue32dbfd2015-01-07 15:55:57 +08003896 SocketListenParam *p_info = (SocketListenParam *)param;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003897
3898 struct sockaddr_un peeraddr;
3899 socklen_t socklen = sizeof (peeraddr);
3900
3901 struct ucred creds;
3902 socklen_t szCreds = sizeof(creds);
3903
3904 struct passwd *pwd = NULL;
3905
Howard Sue32dbfd2015-01-07 15:55:57 +08003906 assert (*p_info->fdCommand < 0);
3907 assert (fd == *p_info->fdListen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003908
Howard Sue32dbfd2015-01-07 15:55:57 +08003909 fdCommand = accept(fd, (sockaddr *) &peeraddr, &socklen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003910
Howard Sue32dbfd2015-01-07 15:55:57 +08003911 if (fdCommand < 0 ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003912 RLOGE("Error on accept() errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003913 /* start listening for new connections again */
Howard Sue32dbfd2015-01-07 15:55:57 +08003914 rilEventAddWakeup(p_info->listen_event);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003915 return;
3916 }
3917
3918 /* check the credential of the other side and only accept socket from
3919 * phone process
3920 */
3921 errno = 0;
3922 is_phone_socket = 0;
3923
Howard Sue32dbfd2015-01-07 15:55:57 +08003924 err = getsockopt(fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003925
3926 if (err == 0 && szCreds > 0) {
3927 errno = 0;
3928 pwd = getpwuid(creds.uid);
3929 if (pwd != NULL) {
Howard Sue32dbfd2015-01-07 15:55:57 +08003930 if (strcmp(pwd->pw_name, p_info->processName) == 0) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003931 is_phone_socket = 1;
3932 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003933 RLOGE("RILD can't accept socket from process %s", pwd->pw_name);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003934 }
3935 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003936 RLOGE("Error on getpwuid() errno: %d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003937 }
3938 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003939 RLOGD("Error on getsockopt() errno: %d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003940 }
3941
Howard Subd82ef12015-04-12 10:25:05 +02003942 if (!is_phone_socket) {
Howard Sue32dbfd2015-01-07 15:55:57 +08003943 RLOGE("RILD must accept socket from %s", p_info->processName);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003944
Howard Sue32dbfd2015-01-07 15:55:57 +08003945 close(fdCommand);
3946 fdCommand = -1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003947
Howard Sue32dbfd2015-01-07 15:55:57 +08003948 onCommandsSocketClosed(p_info->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003949
3950 /* start listening for new connections again */
Howard Sue32dbfd2015-01-07 15:55:57 +08003951 rilEventAddWakeup(p_info->listen_event);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003952
3953 return;
3954 }
3955
Howard Sue32dbfd2015-01-07 15:55:57 +08003956 ret = fcntl(fdCommand, F_SETFL, O_NONBLOCK);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003957
3958 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003959 RLOGE ("Error setting O_NONBLOCK errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003960 }
3961
Howard Sue32dbfd2015-01-07 15:55:57 +08003962 RLOGI("libril: new connection to %s", rilSocketIdToString(p_info->socket_id));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003963
Howard Sue32dbfd2015-01-07 15:55:57 +08003964 p_info->fdCommand = fdCommand;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003965
Howard Sue32dbfd2015-01-07 15:55:57 +08003966 p_rs = record_stream_new(p_info->fdCommand, MAX_COMMAND_BYTES);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003967
Howard Sue32dbfd2015-01-07 15:55:57 +08003968 p_info->p_rs = p_rs;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003969
Howard Sue32dbfd2015-01-07 15:55:57 +08003970 ril_event_set (p_info->commands_event, p_info->fdCommand, 1,
3971 p_info->processCommandsCallback, p_info);
3972
3973 rilEventAddWakeup (p_info->commands_event);
3974
3975 onNewCommandConnect(p_info->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003976}
3977
3978static void freeDebugCallbackArgs(int number, char **args) {
3979 for (int i = 0; i < number; i++) {
3980 if (args[i] != NULL) {
3981 free(args[i]);
3982 }
3983 }
3984 free(args);
3985}
3986
3987static void debugCallback (int fd, short flags, void *param) {
3988 int acceptFD, option;
3989 struct sockaddr_un peeraddr;
3990 socklen_t socklen = sizeof (peeraddr);
3991 int data;
3992 unsigned int qxdm_data[6];
3993 const char *deactData[1] = {"1"};
3994 char *actData[1];
3995 RIL_Dial dialData;
3996 int hangupData[1] = {1};
3997 int number;
3998 char **args;
Howard Sue32dbfd2015-01-07 15:55:57 +08003999 RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
4000 int sim_id = 0;
4001
4002 RLOGI("debugCallback for socket %s", rilSocketIdToString(socket_id));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004003
4004 acceptFD = accept (fd, (sockaddr *) &peeraddr, &socklen);
4005
4006 if (acceptFD < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004007 RLOGE ("error accepting on debug port: %d\n", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004008 return;
4009 }
4010
4011 if (recv(acceptFD, &number, sizeof(int), 0) != sizeof(int)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004012 RLOGE ("error reading on socket: number of Args: \n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004013 return;
4014 }
4015 args = (char **) malloc(sizeof(char*) * number);
4016
4017 for (int i = 0; i < number; i++) {
4018 int len;
4019 if (recv(acceptFD, &len, sizeof(int), 0) != sizeof(int)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004020 RLOGE ("error reading on socket: Len of Args: \n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004021 freeDebugCallbackArgs(i, args);
4022 return;
4023 }
4024 // +1 for null-term
4025 args[i] = (char *) malloc((sizeof(char) * len) + 1);
4026 if (recv(acceptFD, args[i], sizeof(char) * len, 0)
4027 != (int)sizeof(char) * len) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004028 RLOGE ("error reading on socket: Args[%d] \n", i);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004029 freeDebugCallbackArgs(i, args);
4030 return;
4031 }
4032 char * buf = args[i];
4033 buf[len] = 0;
Howard Sue32dbfd2015-01-07 15:55:57 +08004034 if ((i+1) == number) {
4035 /* The last argument should be sim id 0(SIM1)~3(SIM4) */
4036 sim_id = atoi(args[i]);
4037 switch (sim_id) {
4038 case 0:
4039 socket_id = RIL_SOCKET_1;
4040 break;
4041 #if (SIM_COUNT >= 2)
4042 case 1:
4043 socket_id = RIL_SOCKET_2;
4044 break;
4045 #endif
4046 #if (SIM_COUNT >= 3)
4047 case 2:
4048 socket_id = RIL_SOCKET_3;
4049 break;
4050 #endif
4051 #if (SIM_COUNT >= 4)
4052 case 3:
4053 socket_id = RIL_SOCKET_4;
4054 break;
4055 #endif
4056 default:
4057 socket_id = RIL_SOCKET_1;
4058 break;
4059 }
4060 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004061 }
4062
4063 switch (atoi(args[0])) {
4064 case 0:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004065 RLOGI ("Connection on debug port: issuing reset.");
Howard Sue32dbfd2015-01-07 15:55:57 +08004066 issueLocalRequest(RIL_REQUEST_RESET_RADIO, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004067 break;
4068 case 1:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004069 RLOGI ("Connection on debug port: issuing radio power off.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004070 data = 0;
Howard Sue32dbfd2015-01-07 15:55:57 +08004071 issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004072 // Close the socket
Howard Subd82ef12015-04-12 10:25:05 +02004073 if (socket_id == RIL_SOCKET_1 && s_ril_param_socket.fdCommand > 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004074 close(s_ril_param_socket.fdCommand);
4075 s_ril_param_socket.fdCommand = -1;
4076 }
4077 #if (SIM_COUNT == 2)
4078 else if (socket_id == RIL_SOCKET_2 && s_ril_param_socket2.fdCommand > 0) {
4079 close(s_ril_param_socket2.fdCommand);
4080 s_ril_param_socket2.fdCommand = -1;
4081 }
4082 #endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004083 break;
4084 case 2:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004085 RLOGI ("Debug port: issuing unsolicited voice network change.");
Howard Sue32dbfd2015-01-07 15:55:57 +08004086 RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004087 break;
4088 case 3:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004089 RLOGI ("Debug port: QXDM log enable.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004090 qxdm_data[0] = 65536; // head.func_tag
4091 qxdm_data[1] = 16; // head.len
4092 qxdm_data[2] = 1; // mode: 1 for 'start logging'
4093 qxdm_data[3] = 32; // log_file_size: 32megabytes
4094 qxdm_data[4] = 0; // log_mask
4095 qxdm_data[5] = 8; // log_max_fileindex
4096 issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
Howard Sue32dbfd2015-01-07 15:55:57 +08004097 6 * sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004098 break;
4099 case 4:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004100 RLOGI ("Debug port: QXDM log disable.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004101 qxdm_data[0] = 65536;
4102 qxdm_data[1] = 16;
4103 qxdm_data[2] = 0; // mode: 0 for 'stop logging'
4104 qxdm_data[3] = 32;
4105 qxdm_data[4] = 0;
4106 qxdm_data[5] = 8;
4107 issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
Howard Sue32dbfd2015-01-07 15:55:57 +08004108 6 * sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004109 break;
4110 case 5:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004111 RLOGI("Debug port: Radio On");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004112 data = 1;
Howard Sue32dbfd2015-01-07 15:55:57 +08004113 issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004114 sleep(2);
4115 // Set network selection automatic.
Howard Sue32dbfd2015-01-07 15:55:57 +08004116 issueLocalRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004117 break;
4118 case 6:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004119 RLOGI("Debug port: Setup Data Call, Apn :%s\n", args[1]);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004120 actData[0] = args[1];
4121 issueLocalRequest(RIL_REQUEST_SETUP_DATA_CALL, &actData,
Howard Sue32dbfd2015-01-07 15:55:57 +08004122 sizeof(actData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004123 break;
4124 case 7:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004125 RLOGI("Debug port: Deactivate Data Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004126 issueLocalRequest(RIL_REQUEST_DEACTIVATE_DATA_CALL, &deactData,
Howard Sue32dbfd2015-01-07 15:55:57 +08004127 sizeof(deactData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004128 break;
4129 case 8:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004130 RLOGI("Debug port: Dial Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004131 dialData.clir = 0;
4132 dialData.address = args[1];
Howard Sue32dbfd2015-01-07 15:55:57 +08004133 issueLocalRequest(RIL_REQUEST_DIAL, &dialData, sizeof(dialData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004134 break;
4135 case 9:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004136 RLOGI("Debug port: Answer Call");
Howard Sue32dbfd2015-01-07 15:55:57 +08004137 issueLocalRequest(RIL_REQUEST_ANSWER, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004138 break;
4139 case 10:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004140 RLOGI("Debug port: End Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004141 issueLocalRequest(RIL_REQUEST_HANGUP, &hangupData,
Howard Sue32dbfd2015-01-07 15:55:57 +08004142 sizeof(hangupData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004143 break;
4144 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004145 RLOGE ("Invalid request");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004146 break;
4147 }
4148 freeDebugCallbackArgs(number, args);
4149 close(acceptFD);
4150}
4151
4152
4153static void userTimerCallback (int fd, short flags, void *param) {
4154 UserCallbackInfo *p_info;
4155
4156 p_info = (UserCallbackInfo *)param;
4157
4158 p_info->p_callback(p_info->userParam);
4159
4160
4161 // FIXME generalize this...there should be a cancel mechanism
4162 if (s_last_wake_timeout_info != NULL && s_last_wake_timeout_info == p_info) {
4163 s_last_wake_timeout_info = NULL;
4164 }
4165
4166 free(p_info);
4167}
4168
4169
4170static void *
4171eventLoop(void *param) {
4172 int ret;
4173 int filedes[2];
4174
4175 ril_event_init();
4176
4177 pthread_mutex_lock(&s_startupMutex);
4178
4179 s_started = 1;
4180 pthread_cond_broadcast(&s_startupCond);
4181
4182 pthread_mutex_unlock(&s_startupMutex);
4183
4184 ret = pipe(filedes);
4185
4186 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004187 RLOGE("Error in pipe() errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004188 return NULL;
4189 }
4190
4191 s_fdWakeupRead = filedes[0];
4192 s_fdWakeupWrite = filedes[1];
4193
4194 fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
4195
4196 ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
4197 processWakeupCallback, NULL);
4198
4199 rilEventAddWakeup (&s_wakeupfd_event);
4200
4201 // Only returns on error
4202 ril_event_loop();
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004203 RLOGE ("error in event_loop_base errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004204 // kill self to restart on error
4205 kill(0, SIGKILL);
4206
4207 return NULL;
4208}
4209
4210extern "C" void
4211RIL_startEventLoop(void) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004212 /* spin up eventLoop thread and wait for it to get started */
4213 s_started = 0;
4214 pthread_mutex_lock(&s_startupMutex);
4215
Howard Sue32dbfd2015-01-07 15:55:57 +08004216 pthread_attr_t attr;
4217 pthread_attr_init(&attr);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004218 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
Howard Sue32dbfd2015-01-07 15:55:57 +08004219
4220 int result = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
4221 if (result != 0) {
4222 RLOGE("Failed to create dispatch thread: %s", strerror(result));
4223 goto done;
4224 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004225
4226 while (s_started == 0) {
4227 pthread_cond_wait(&s_startupCond, &s_startupMutex);
4228 }
4229
Howard Sue32dbfd2015-01-07 15:55:57 +08004230done:
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004231 pthread_mutex_unlock(&s_startupMutex);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004232}
4233
4234// Used for testing purpose only.
4235extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) {
4236 memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
4237}
4238
Howard Sue32dbfd2015-01-07 15:55:57 +08004239static void startListen(RIL_SOCKET_ID socket_id, SocketListenParam* socket_listen_p) {
4240 int fdListen = -1;
4241 int ret;
4242 char socket_name[10];
4243
4244 memset(socket_name, 0, sizeof(char)*10);
4245
4246 switch(socket_id) {
4247 case RIL_SOCKET_1:
4248 strncpy(socket_name, RIL_getRilSocketName(), 9);
4249 break;
4250 #if (SIM_COUNT >= 2)
4251 case RIL_SOCKET_2:
4252 strncpy(socket_name, SOCKET2_NAME_RIL, 9);
4253 break;
4254 #endif
4255 #if (SIM_COUNT >= 3)
4256 case RIL_SOCKET_3:
4257 strncpy(socket_name, SOCKET3_NAME_RIL, 9);
4258 break;
4259 #endif
4260 #if (SIM_COUNT >= 4)
4261 case RIL_SOCKET_4:
4262 strncpy(socket_name, SOCKET4_NAME_RIL, 9);
4263 break;
4264 #endif
4265 default:
4266 RLOGE("Socket id is wrong!!");
4267 return;
4268 }
4269
4270 RLOGI("Start to listen %s", rilSocketIdToString(socket_id));
4271
4272 fdListen = android_get_control_socket(socket_name);
4273 if (fdListen < 0) {
4274 RLOGE("Failed to get socket %s", socket_name);
4275 exit(-1);
4276 }
4277
4278 ret = listen(fdListen, 4);
4279
4280 if (ret < 0) {
4281 RLOGE("Failed to listen on control socket '%d': %s",
4282 fdListen, strerror(errno));
4283 exit(-1);
4284 }
4285 socket_listen_p->fdListen = fdListen;
4286
4287 /* note: non-persistent so we can accept only one connection at a time */
4288 ril_event_set (socket_listen_p->listen_event, fdListen, false,
4289 listenCallback, socket_listen_p);
4290
4291 rilEventAddWakeup (socket_listen_p->listen_event);
4292}
4293
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004294extern "C" void
4295RIL_register (const RIL_RadioFunctions *callbacks) {
4296 int ret;
4297 int flags;
4298
Howard Sue32dbfd2015-01-07 15:55:57 +08004299 RLOGI("SIM_COUNT: %d", SIM_COUNT);
4300
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004301 if (callbacks == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004302 RLOGE("RIL_register: RIL_RadioFunctions * null");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004303 return;
4304 }
4305 if (callbacks->version < RIL_VERSION_MIN) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004306 RLOGE("RIL_register: version %d is to old, min version is %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004307 callbacks->version, RIL_VERSION_MIN);
4308 return;
4309 }
4310 if (callbacks->version > RIL_VERSION) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004311 RLOGE("RIL_register: version %d is too new, max version is %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004312 callbacks->version, RIL_VERSION);
4313 return;
4314 }
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004315 RLOGE("RIL_register: RIL version %d", callbacks->version);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004316
4317 if (s_registerCalled > 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004318 RLOGE("RIL_register has been called more than once. "
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004319 "Subsequent call ignored");
4320 return;
4321 }
4322
4323 memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
4324
Howard Sue32dbfd2015-01-07 15:55:57 +08004325 /* Initialize socket1 parameters */
4326 s_ril_param_socket = {
4327 RIL_SOCKET_1, /* socket_id */
4328 -1, /* fdListen */
4329 -1, /* fdCommand */
4330 PHONE_PROCESS, /* processName */
4331 &s_commands_event, /* commands_event */
4332 &s_listen_event, /* listen_event */
4333 processCommandsCallback, /* processCommandsCallback */
4334 NULL /* p_rs */
4335 };
4336
4337#if (SIM_COUNT >= 2)
4338 s_ril_param_socket2 = {
4339 RIL_SOCKET_2, /* socket_id */
4340 -1, /* fdListen */
4341 -1, /* fdCommand */
4342 PHONE_PROCESS, /* processName */
4343 &s_commands_event_socket2, /* commands_event */
4344 &s_listen_event_socket2, /* listen_event */
4345 processCommandsCallback, /* processCommandsCallback */
4346 NULL /* p_rs */
4347 };
4348#endif
4349
4350#if (SIM_COUNT >= 3)
4351 s_ril_param_socket3 = {
4352 RIL_SOCKET_3, /* socket_id */
4353 -1, /* fdListen */
4354 -1, /* fdCommand */
4355 PHONE_PROCESS, /* processName */
4356 &s_commands_event_socket3, /* commands_event */
4357 &s_listen_event_socket3, /* listen_event */
4358 processCommandsCallback, /* processCommandsCallback */
4359 NULL /* p_rs */
4360 };
4361#endif
4362
4363#if (SIM_COUNT >= 4)
4364 s_ril_param_socket4 = {
4365 RIL_SOCKET_4, /* socket_id */
4366 -1, /* fdListen */
4367 -1, /* fdCommand */
4368 PHONE_PROCESS, /* processName */
4369 &s_commands_event_socket4, /* commands_event */
4370 &s_listen_event_socket4, /* listen_event */
4371 processCommandsCallback, /* processCommandsCallback */
4372 NULL /* p_rs */
4373 };
4374#endif
4375
Howard Subd82ef12015-04-12 10:25:05 +02004376
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004377 s_registerCalled = 1;
4378
Howard Sue32dbfd2015-01-07 15:55:57 +08004379 RLOGI("s_registerCalled flag set, %d", s_started);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004380 // Little self-check
4381
4382 for (int i = 0; i < (int)NUM_ELEMS(s_commands); i++) {
4383 assert(i == s_commands[i].requestNumber);
4384 }
4385
Howard Subd82ef12015-04-12 10:25:05 +02004386 for (int i = 0; i < (int)NUM_ELEMS(s_commands_v); i++) {
4387 assert(i + RIL_VENDOR_COMMANDS_OFFSET == s_commands[i].requestNumber);
4388 }
4389
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004390 for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses); i++) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004391 assert(i + RIL_UNSOL_RESPONSE_BASE
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004392 == s_unsolResponses[i].requestNumber);
4393 }
4394
Howard Subd82ef12015-04-12 10:25:05 +02004395 for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses_v); i++) {
4396 assert(i + RIL_UNSOL_RESPONSE_BASE + RIL_VENDOR_COMMANDS_OFFSET
4397 == s_unsolResponses[i].requestNumber);
4398 }
4399
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004400 // New rild impl calls RIL_startEventLoop() first
4401 // old standalone impl wants it here.
4402
4403 if (s_started == 0) {
4404 RIL_startEventLoop();
4405 }
4406
Howard Sue32dbfd2015-01-07 15:55:57 +08004407 // start listen socket1
4408 startListen(RIL_SOCKET_1, &s_ril_param_socket);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004409
Howard Sue32dbfd2015-01-07 15:55:57 +08004410#if (SIM_COUNT >= 2)
4411 // start listen socket2
4412 startListen(RIL_SOCKET_2, &s_ril_param_socket2);
4413#endif /* (SIM_COUNT == 2) */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004414
Howard Sue32dbfd2015-01-07 15:55:57 +08004415#if (SIM_COUNT >= 3)
4416 // start listen socket3
4417 startListen(RIL_SOCKET_3, &s_ril_param_socket3);
4418#endif /* (SIM_COUNT == 3) */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004419
Howard Sue32dbfd2015-01-07 15:55:57 +08004420#if (SIM_COUNT >= 4)
4421 // start listen socket4
4422 startListen(RIL_SOCKET_4, &s_ril_param_socket4);
4423#endif /* (SIM_COUNT == 4) */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004424
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004425
4426#if 1
4427 // start debug interface socket
4428
Howard Sue32dbfd2015-01-07 15:55:57 +08004429 char *inst = NULL;
4430 if (strlen(RIL_getRilSocketName()) >= strlen(SOCKET_NAME_RIL)) {
4431 inst = RIL_getRilSocketName() + strlen(SOCKET_NAME_RIL);
4432 }
4433
4434 char rildebug[MAX_DEBUG_SOCKET_NAME_LENGTH] = SOCKET_NAME_RIL_DEBUG;
4435 if (inst != NULL) {
Andreas Schneider3063dc12015-04-13 23:04:05 +02004436 snprintf(rildebug, sizeof(rildebug), "%s%s", SOCKET_NAME_RIL_DEBUG, inst);
Howard Sue32dbfd2015-01-07 15:55:57 +08004437 }
4438
4439 s_fdDebug = android_get_control_socket(rildebug);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004440 if (s_fdDebug < 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004441 RLOGE("Failed to get socket : %s errno:%d", rildebug, errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004442 exit(-1);
4443 }
4444
4445 ret = listen(s_fdDebug, 4);
4446
4447 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004448 RLOGE("Failed to listen on ril debug socket '%d': %s",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004449 s_fdDebug, strerror(errno));
4450 exit(-1);
4451 }
4452
4453 ril_event_set (&s_debug_event, s_fdDebug, true,
4454 debugCallback, NULL);
4455
4456 rilEventAddWakeup (&s_debug_event);
4457#endif
4458
4459}
4460
4461static int
4462checkAndDequeueRequestInfo(struct RequestInfo *pRI) {
4463 int ret = 0;
Howard Sue32dbfd2015-01-07 15:55:57 +08004464 /* Hook for current context
4465 pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
4466 pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
4467 /* pendingRequestsHook refer to &s_pendingRequests */
4468 RequestInfo ** pendingRequestsHook = &s_pendingRequests;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004469
4470 if (pRI == NULL) {
4471 return 0;
4472 }
4473
Howard Sue32dbfd2015-01-07 15:55:57 +08004474#if (SIM_COUNT >= 2)
4475 if (pRI->socket_id == RIL_SOCKET_2) {
4476 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
4477 pendingRequestsHook = &s_pendingRequests_socket2;
4478 }
4479#if (SIM_COUNT >= 3)
4480 if (pRI->socket_id == RIL_SOCKET_3) {
4481 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
4482 pendingRequestsHook = &s_pendingRequests_socket3;
4483 }
4484#endif
4485#if (SIM_COUNT >= 4)
4486 if (pRI->socket_id == RIL_SOCKET_4) {
4487 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
4488 pendingRequestsHook = &s_pendingRequests_socket4;
4489 }
4490#endif
4491#endif
4492 pthread_mutex_lock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004493
Howard Sue32dbfd2015-01-07 15:55:57 +08004494 for(RequestInfo **ppCur = pendingRequestsHook
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004495 ; *ppCur != NULL
4496 ; ppCur = &((*ppCur)->p_next)
4497 ) {
4498 if (pRI == *ppCur) {
4499 ret = 1;
4500
4501 *ppCur = (*ppCur)->p_next;
4502 break;
4503 }
4504 }
4505
Howard Sue32dbfd2015-01-07 15:55:57 +08004506 pthread_mutex_unlock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004507
4508 return ret;
4509}
4510
4511
4512extern "C" void
4513RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
4514 RequestInfo *pRI;
4515 int ret;
Howard Sue32dbfd2015-01-07 15:55:57 +08004516 int fd = s_ril_param_socket.fdCommand;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004517 size_t errorOffset;
Howard Sue32dbfd2015-01-07 15:55:57 +08004518 RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004519
4520 pRI = (RequestInfo *)t;
4521
4522 if (!checkAndDequeueRequestInfo(pRI)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004523 RLOGE ("RIL_onRequestComplete: invalid RIL_Token");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004524 return;
4525 }
4526
Howard Sue32dbfd2015-01-07 15:55:57 +08004527 socket_id = pRI->socket_id;
4528#if (SIM_COUNT >= 2)
4529 if (socket_id == RIL_SOCKET_2) {
4530 fd = s_ril_param_socket2.fdCommand;
4531 }
4532#if (SIM_COUNT >= 3)
4533 if (socket_id == RIL_SOCKET_3) {
4534 fd = s_ril_param_socket3.fdCommand;
4535 }
4536#endif
4537#if (SIM_COUNT >= 4)
4538 if (socket_id == RIL_SOCKET_4) {
4539 fd = s_ril_param_socket4.fdCommand;
4540 }
4541#endif
4542#endif
4543 RLOGD("RequestComplete, %s", rilSocketIdToString(socket_id));
4544
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004545 if (pRI->local > 0) {
4546 // Locally issued command...void only!
4547 // response does not go back up the command socket
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004548 RLOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004549
4550 goto done;
4551 }
4552
4553 appendPrintBuf("[%04d]< %s",
4554 pRI->token, requestToString(pRI->pCI->requestNumber));
4555
4556 if (pRI->cancelled == 0) {
4557 Parcel p;
4558
4559 p.writeInt32 (RESPONSE_SOLICITED);
4560 p.writeInt32 (pRI->token);
4561 errorOffset = p.dataPosition();
4562
4563 p.writeInt32 (e);
4564
4565 if (response != NULL) {
4566 // there is a response payload, no matter success or not.
4567 ret = pRI->pCI->responseFunction(p, response, responselen);
4568
4569 /* if an error occurred, rewind and mark it */
4570 if (ret != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004571 RLOGE ("responseFunction error, ret %d", ret);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004572 p.setDataPosition(errorOffset);
4573 p.writeInt32 (ret);
4574 }
4575 }
4576
4577 if (e != RIL_E_SUCCESS) {
4578 appendPrintBuf("%s fails by %s", printBuf, failCauseToString(e));
4579 }
4580
Howard Sue32dbfd2015-01-07 15:55:57 +08004581 if (fd < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004582 RLOGD ("RIL onRequestComplete: Command channel closed");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004583 }
Howard Sue32dbfd2015-01-07 15:55:57 +08004584 sendResponse(p, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004585 }
4586
4587done:
4588 free(pRI);
4589}
4590
Howard Subd82ef12015-04-12 10:25:05 +02004591
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004592static void
4593grabPartialWakeLock() {
4594 acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
4595}
4596
4597static void
4598releaseWakeLock() {
4599 release_wake_lock(ANDROID_WAKE_LOCK_NAME);
4600}
4601
4602/**
4603 * Timer callback to put us back to sleep before the default timeout
4604 */
4605static void
4606wakeTimeoutCallback (void *param) {
4607 // We're using "param != NULL" as a cancellation mechanism
4608 if (param == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004609 //RLOGD("wakeTimeout: releasing wake lock");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004610
4611 releaseWakeLock();
4612 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004613 //RLOGD("wakeTimeout: releasing wake lock CANCELLED");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004614 }
4615}
4616
4617static int
4618decodeVoiceRadioTechnology (RIL_RadioState radioState) {
4619 switch (radioState) {
4620 case RADIO_STATE_SIM_NOT_READY:
4621 case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
4622 case RADIO_STATE_SIM_READY:
4623 return RADIO_TECH_UMTS;
4624
4625 case RADIO_STATE_RUIM_NOT_READY:
4626 case RADIO_STATE_RUIM_READY:
4627 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
4628 case RADIO_STATE_NV_NOT_READY:
4629 case RADIO_STATE_NV_READY:
4630 return RADIO_TECH_1xRTT;
4631
4632 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004633 RLOGD("decodeVoiceRadioTechnology: Invoked with incorrect RadioState");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004634 return -1;
4635 }
4636}
4637
4638static int
4639decodeCdmaSubscriptionSource (RIL_RadioState radioState) {
4640 switch (radioState) {
4641 case RADIO_STATE_SIM_NOT_READY:
4642 case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
4643 case RADIO_STATE_SIM_READY:
4644 case RADIO_STATE_RUIM_NOT_READY:
4645 case RADIO_STATE_RUIM_READY:
4646 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
4647 return CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM;
4648
4649 case RADIO_STATE_NV_NOT_READY:
4650 case RADIO_STATE_NV_READY:
4651 return CDMA_SUBSCRIPTION_SOURCE_NV;
4652
4653 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004654 RLOGD("decodeCdmaSubscriptionSource: Invoked with incorrect RadioState");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004655 return -1;
4656 }
4657}
4658
4659static int
4660decodeSimStatus (RIL_RadioState radioState) {
4661 switch (radioState) {
4662 case RADIO_STATE_SIM_NOT_READY:
4663 case RADIO_STATE_RUIM_NOT_READY:
4664 case RADIO_STATE_NV_NOT_READY:
4665 case RADIO_STATE_NV_READY:
4666 return -1;
4667 case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
4668 case RADIO_STATE_SIM_READY:
4669 case RADIO_STATE_RUIM_READY:
4670 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
4671 return radioState;
4672 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004673 RLOGD("decodeSimStatus: Invoked with incorrect RadioState");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004674 return -1;
4675 }
4676}
4677
4678static bool is3gpp2(int radioTech) {
4679 switch (radioTech) {
4680 case RADIO_TECH_IS95A:
4681 case RADIO_TECH_IS95B:
4682 case RADIO_TECH_1xRTT:
4683 case RADIO_TECH_EVDO_0:
4684 case RADIO_TECH_EVDO_A:
4685 case RADIO_TECH_EVDO_B:
4686 case RADIO_TECH_EHRPD:
4687 return true;
4688 default:
4689 return false;
4690 }
4691}
4692
4693/* If RIL sends SIM states or RUIM states, store the voice radio
4694 * technology and subscription source information so that they can be
4695 * returned when telephony framework requests them
4696 */
4697static RIL_RadioState
Howard Subd82ef12015-04-12 10:25:05 +02004698processRadioState(RIL_RadioState newRadioState, RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004699
4700 if((newRadioState > RADIO_STATE_UNAVAILABLE) && (newRadioState < RADIO_STATE_ON)) {
4701 int newVoiceRadioTech;
4702 int newCdmaSubscriptionSource;
4703 int newSimStatus;
4704
4705 /* This is old RIL. Decode Subscription source and Voice Radio Technology
4706 from Radio State and send change notifications if there has been a change */
4707 newVoiceRadioTech = decodeVoiceRadioTechnology(newRadioState);
4708 if(newVoiceRadioTech != voiceRadioTech) {
4709 voiceRadioTech = newVoiceRadioTech;
Howard Sue32dbfd2015-01-07 15:55:57 +08004710 RIL_UNSOL_RESPONSE(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED,
4711 &voiceRadioTech, sizeof(voiceRadioTech), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004712 }
4713 if(is3gpp2(newVoiceRadioTech)) {
4714 newCdmaSubscriptionSource = decodeCdmaSubscriptionSource(newRadioState);
4715 if(newCdmaSubscriptionSource != cdmaSubscriptionSource) {
4716 cdmaSubscriptionSource = newCdmaSubscriptionSource;
Howard Sue32dbfd2015-01-07 15:55:57 +08004717 RIL_UNSOL_RESPONSE(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED,
4718 &cdmaSubscriptionSource, sizeof(cdmaSubscriptionSource), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004719 }
4720 }
4721 newSimStatus = decodeSimStatus(newRadioState);
4722 if(newSimStatus != simRuimStatus) {
4723 simRuimStatus = newSimStatus;
Howard Sue32dbfd2015-01-07 15:55:57 +08004724 RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004725 }
4726
4727 /* Send RADIO_ON to telephony */
4728 newRadioState = RADIO_STATE_ON;
4729 }
4730
4731 return newRadioState;
4732}
4733
Howard Subd82ef12015-04-12 10:25:05 +02004734
Howard Sue32dbfd2015-01-07 15:55:57 +08004735#if defined(ANDROID_MULTI_SIM)
4736extern "C"
Andreas Schneider47b2d962015-04-13 22:54:49 +02004737void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
Howard Sue32dbfd2015-01-07 15:55:57 +08004738 size_t datalen, RIL_SOCKET_ID socket_id)
4739#else
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004740extern "C"
Andreas Schneider47b2d962015-04-13 22:54:49 +02004741void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004742 size_t datalen)
Howard Sue32dbfd2015-01-07 15:55:57 +08004743#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004744{
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004745 int ret;
4746 int64_t timeReceived = 0;
4747 bool shouldScheduleTimeout = false;
4748 RIL_RadioState newState;
Howard Sue32dbfd2015-01-07 15:55:57 +08004749 RIL_SOCKET_ID soc_id = RIL_SOCKET_1;
Howard Subd82ef12015-04-12 10:25:05 +02004750 UnsolResponseInfo *pRI = NULL;
Howard Sue32dbfd2015-01-07 15:55:57 +08004751
4752#if defined(ANDROID_MULTI_SIM)
4753 soc_id = socket_id;
4754#endif
4755
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004756
4757 if (s_registerCalled == 0) {
4758 // Ignore RIL_onUnsolicitedResponse before RIL_register
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004759 RLOGW("RIL_onUnsolicitedResponse called before RIL_register");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004760 return;
4761 }
Howard Sue32dbfd2015-01-07 15:55:57 +08004762
Howard Subd82ef12015-04-12 10:25:05 +02004763 /* Hack to include Samsung responses */
4764 if (unsolResponse > RIL_VENDOR_COMMANDS_OFFSET + RIL_UNSOL_RESPONSE_BASE) {
4765 int index = unsolResponse - RIL_VENDOR_COMMANDS_OFFSET - RIL_UNSOL_RESPONSE_BASE;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004766
Howard Subd82ef12015-04-12 10:25:05 +02004767 RLOGD("SAMSUNG: unsolResponse=%d, unsolResponseIndex=%d", unsolResponse, index);
4768
4769 if (index < (int32_t)NUM_ELEMS(s_unsolResponses_v))
4770 pRI = &s_unsolResponses_v[index];
4771 } else {
4772 int index = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
4773 if (index < (int32_t)NUM_ELEMS(s_unsolResponses))
4774 pRI = &s_unsolResponses[index];
4775 }
4776
4777 if (pRI == NULL || pRI->responseFunction == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004778 RLOGE("unsupported unsolicited response code %d", unsolResponse);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004779 return;
4780 }
4781
4782 // Grab a wake lock if needed for this reponse,
4783 // as we exit we'll either release it immediately
4784 // or set a timer to release it later.
Howard Subd82ef12015-04-12 10:25:05 +02004785 switch (pRI->wakeType) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004786 case WAKE_PARTIAL:
4787 grabPartialWakeLock();
4788 shouldScheduleTimeout = true;
4789 break;
4790
4791 case DONT_WAKE:
4792 default:
4793 // No wake lock is grabed so don't set timeout
4794 shouldScheduleTimeout = false;
4795 break;
4796 }
4797
4798 // Mark the time this was received, doing this
4799 // after grabing the wakelock incase getting
4800 // the elapsedRealTime might cause us to goto
4801 // sleep.
4802 if (unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
4803 timeReceived = elapsedRealtime();
4804 }
4805
4806 appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
4807
4808 Parcel p;
4809
4810 p.writeInt32 (RESPONSE_UNSOLICITED);
4811 p.writeInt32 (unsolResponse);
4812
Howard Subd82ef12015-04-12 10:25:05 +02004813 ret = pRI->responseFunction(p, const_cast<void*>(data), datalen);
4814
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004815 if (ret != 0) {
4816 // Problem with the response. Don't continue;
4817 goto error_exit;
4818 }
4819
4820 // some things get more payload
4821 switch(unsolResponse) {
4822 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
Howard Sue32dbfd2015-01-07 15:55:57 +08004823 newState = processRadioState(CALL_ONSTATEREQUEST(soc_id), soc_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004824 p.writeInt32(newState);
4825 appendPrintBuf("%s {%s}", printBuf,
Howard Sue32dbfd2015-01-07 15:55:57 +08004826 radioStateToString(CALL_ONSTATEREQUEST(soc_id)));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004827 break;
4828
4829
4830 case RIL_UNSOL_NITZ_TIME_RECEIVED:
4831 // Store the time that this was received so the
4832 // handler of this message can account for
4833 // the time it takes to arrive and process. In
4834 // particular the system has been known to sleep
4835 // before this message can be processed.
4836 p.writeInt64(timeReceived);
4837 break;
4838 }
4839
Howard Sue32dbfd2015-01-07 15:55:57 +08004840 RLOGI("%s UNSOLICITED: %s length:%d", rilSocketIdToString(soc_id), requestToString(unsolResponse), p.dataSize());
4841 ret = sendResponse(p, soc_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004842 if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
4843
4844 // Unfortunately, NITZ time is not poll/update like everything
4845 // else in the system. So, if the upstream client isn't connected,
4846 // keep a copy of the last NITZ response (with receive time noted
4847 // above) around so we can deliver it when it is connected
4848
4849 if (s_lastNITZTimeData != NULL) {
4850 free (s_lastNITZTimeData);
4851 s_lastNITZTimeData = NULL;
4852 }
4853
4854 s_lastNITZTimeData = malloc(p.dataSize());
4855 s_lastNITZTimeDataSize = p.dataSize();
4856 memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
4857 }
4858
4859 // For now, we automatically go back to sleep after TIMEVAL_WAKE_TIMEOUT
4860 // FIXME The java code should handshake here to release wake lock
4861
4862 if (shouldScheduleTimeout) {
4863 // Cancel the previous request
4864 if (s_last_wake_timeout_info != NULL) {
4865 s_last_wake_timeout_info->userParam = (void *)1;
4866 }
4867
4868 s_last_wake_timeout_info
4869 = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
4870 &TIMEVAL_WAKE_TIMEOUT);
4871 }
4872
4873 // Normal exit
4874 return;
4875
4876error_exit:
4877 if (shouldScheduleTimeout) {
4878 releaseWakeLock();
4879 }
4880}
4881
4882/** FIXME generalize this if you track UserCAllbackInfo, clear it
4883 when the callback occurs
4884*/
4885static UserCallbackInfo *
4886internalRequestTimedCallback (RIL_TimedCallback callback, void *param,
4887 const struct timeval *relativeTime)
4888{
4889 struct timeval myRelativeTime;
4890 UserCallbackInfo *p_info;
4891
4892 p_info = (UserCallbackInfo *) malloc (sizeof(UserCallbackInfo));
4893
4894 p_info->p_callback = callback;
4895 p_info->userParam = param;
4896
4897 if (relativeTime == NULL) {
4898 /* treat null parameter as a 0 relative time */
4899 memset (&myRelativeTime, 0, sizeof(myRelativeTime));
4900 } else {
4901 /* FIXME I think event_add's tv param is really const anyway */
4902 memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime));
4903 }
4904
4905 ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info);
4906
4907 ril_timer_add(&(p_info->event), &myRelativeTime);
4908
4909 triggerEvLoop();
4910 return p_info;
4911}
4912
4913
4914extern "C" void
4915RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
4916 const struct timeval *relativeTime) {
4917 internalRequestTimedCallback (callback, param, relativeTime);
4918}
4919
4920const char *
4921failCauseToString(RIL_Errno e) {
4922 switch(e) {
4923 case RIL_E_SUCCESS: return "E_SUCCESS";
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004924 case RIL_E_RADIO_NOT_AVAILABLE: return "E_RADIO_NOT_AVAILABLE";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004925 case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE";
4926 case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT";
4927 case RIL_E_SIM_PIN2: return "E_SIM_PIN2";
4928 case RIL_E_SIM_PUK2: return "E_SIM_PUK2";
4929 case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED";
4930 case RIL_E_CANCELLED: return "E_CANCELLED";
4931 case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL";
4932 case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW";
4933 case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY";
4934 case RIL_E_SIM_ABSENT:return "E_SIM_ABSENT";
4935 case RIL_E_ILLEGAL_SIM_OR_ME:return "E_ILLEGAL_SIM_OR_ME";
4936#ifdef FEATURE_MULTIMODE_ANDROID
4937 case RIL_E_SUBSCRIPTION_NOT_AVAILABLE:return "E_SUBSCRIPTION_NOT_AVAILABLE";
4938 case RIL_E_MODE_NOT_SUPPORTED:return "E_MODE_NOT_SUPPORTED";
4939#endif
4940 default: return "<unknown error>";
4941 }
4942}
4943
4944const char *
4945radioStateToString(RIL_RadioState s) {
4946 switch(s) {
4947 case RADIO_STATE_OFF: return "RADIO_OFF";
4948 case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE";
4949 case RADIO_STATE_SIM_NOT_READY: return "RADIO_SIM_NOT_READY";
4950 case RADIO_STATE_SIM_LOCKED_OR_ABSENT: return "RADIO_SIM_LOCKED_OR_ABSENT";
4951 case RADIO_STATE_SIM_READY: return "RADIO_SIM_READY";
4952 case RADIO_STATE_RUIM_NOT_READY:return"RADIO_RUIM_NOT_READY";
4953 case RADIO_STATE_RUIM_READY:return"RADIO_RUIM_READY";
4954 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:return"RADIO_RUIM_LOCKED_OR_ABSENT";
4955 case RADIO_STATE_NV_NOT_READY:return"RADIO_NV_NOT_READY";
4956 case RADIO_STATE_NV_READY:return"RADIO_NV_READY";
4957 case RADIO_STATE_ON:return"RADIO_ON";
4958 default: return "<unknown state>";
4959 }
4960}
4961
4962const char *
4963callStateToString(RIL_CallState s) {
4964 switch(s) {
4965 case RIL_CALL_ACTIVE : return "ACTIVE";
4966 case RIL_CALL_HOLDING: return "HOLDING";
4967 case RIL_CALL_DIALING: return "DIALING";
4968 case RIL_CALL_ALERTING: return "ALERTING";
4969 case RIL_CALL_INCOMING: return "INCOMING";
4970 case RIL_CALL_WAITING: return "WAITING";
4971 default: return "<unknown state>";
4972 }
4973}
4974
4975const char *
4976requestToString(int request) {
4977/*
4978 cat libs/telephony/ril_commands.h \
4979 | egrep "^ *{RIL_" \
4980 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
4981
4982
4983 cat libs/telephony/ril_unsol_commands.h \
4984 | egrep "^ *{RIL_" \
4985 | sed -re 's/\{RIL_([^,]+),([^}]+).+/case RIL_\1: return "\1";/'
4986
4987*/
4988 switch(request) {
4989 case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
4990 case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
4991 case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
4992 case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
4993 case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
4994 case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
4995 case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
4996 case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
4997 case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
4998 case RIL_REQUEST_DIAL: return "DIAL";
4999 case RIL_REQUEST_DIAL_EMERGENCY: return "DIAL";
5000 case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
5001 case RIL_REQUEST_HANGUP: return "HANGUP";
5002 case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
5003 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
5004 case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
5005 case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
5006 case RIL_REQUEST_UDUB: return "UDUB";
5007 case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
5008 case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
5009 case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
5010 case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
5011 case RIL_REQUEST_OPERATOR: return "OPERATOR";
5012 case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
5013 case RIL_REQUEST_DTMF: return "DTMF";
5014 case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
5015 case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
5016 case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
5017 case RIL_REQUEST_SIM_IO: return "SIM_IO";
5018 case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
5019 case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
5020 case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
5021 case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
5022 case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
5023 case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
5024 case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
5025 case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
5026 case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
5027 case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
5028 case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
5029 case RIL_REQUEST_ANSWER: return "ANSWER";
5030 case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
5031 case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
5032 case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
5033 case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
5034 case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
5035 case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
5036 case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
5037 case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
5038 case RIL_REQUEST_DTMF_START: return "DTMF_START";
5039 case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
5040 case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
5041 case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
5042 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE";
5043 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE";
5044 case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS";
5045 case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
5046 case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
5047 case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
5048 case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
5049 case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
5050 case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
5051 case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
5052 case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
5053 case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
5054 case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
5055 case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE";
5056 case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE";
5057 case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND";
5058 case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE";
5059 case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
5060 case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
5061 case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER";
5062 case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES";
XpLoDWilDba5c6a32013-07-27 21:12:19 +02005063 case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:return"CDMA_SET_SUBSCRIPTION_SOURCE";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005064 case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:return"CDMA_SET_ROAMING_PREFERENCE";
5065 case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:return"CDMA_QUERY_ROAMING_PREFERENCE";
5066 case RIL_REQUEST_SET_TTY_MODE:return"SET_TTY_MODE";
5067 case RIL_REQUEST_QUERY_TTY_MODE:return"QUERY_TTY_MODE";
5068 case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
5069 case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
5070 case RIL_REQUEST_CDMA_FLASH:return"CDMA_FLASH";
5071 case RIL_REQUEST_CDMA_BURST_DTMF:return"CDMA_BURST_DTMF";
5072 case RIL_REQUEST_CDMA_SEND_SMS:return"CDMA_SEND_SMS";
5073 case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:return"CDMA_SMS_ACKNOWLEDGE";
5074 case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG:return"GSM_GET_BROADCAST_SMS_CONFIG";
5075 case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG:return"GSM_SET_BROADCAST_SMS_CONFIG";
5076 case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG:return "CDMA_GET_BROADCAST_SMS_CONFIG";
5077 case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG:return "CDMA_SET_BROADCAST_SMS_CONFIG";
5078 case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION:return "CDMA_SMS_BROADCAST_ACTIVATION";
Ethan Chend6e30652013-08-04 22:49:56 -07005079 case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return"CDMA_VALIDATE_AND_WRITE_AKEY";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005080 case RIL_REQUEST_CDMA_SUBSCRIPTION: return"CDMA_SUBSCRIPTION";
5081 case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "CDMA_WRITE_SMS_TO_RUIM";
5082 case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "CDMA_DELETE_SMS_ON_RUIM";
5083 case RIL_REQUEST_DEVICE_IDENTITY: return "DEVICE_IDENTITY";
5084 case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "EXIT_EMERGENCY_CALLBACK_MODE";
5085 case RIL_REQUEST_GET_SMSC_ADDRESS: return "GET_SMSC_ADDRESS";
5086 case RIL_REQUEST_SET_SMSC_ADDRESS: return "SET_SMSC_ADDRESS";
5087 case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "REPORT_SMS_MEMORY_STATUS";
5088 case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "REPORT_STK_SERVICE_IS_RUNNING";
5089 case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "CDMA_GET_SUBSCRIPTION_SOURCE";
5090 case RIL_REQUEST_ISIM_AUTHENTICATION: return "ISIM_AUTHENTICATION";
5091 case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
5092 case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
5093 case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH";
XpLoDWilDba5c6a32013-07-27 21:12:19 +02005094 case RIL_REQUEST_GET_CELL_INFO_LIST: return"GET_CELL_INFO_LIST";
5095 case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return"SET_UNSOL_CELL_INFO_LIST_RATE";
Andrew Jiangca4a9a02014-01-18 18:04:08 -05005096 case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "RIL_REQUEST_SET_INITIAL_ATTACH_APN";
5097 case RIL_REQUEST_IMS_REGISTRATION_STATE: return "IMS_REGISTRATION_STATE";
5098 case RIL_REQUEST_IMS_SEND_SMS: return "IMS_SEND_SMS";
Howard Sue32dbfd2015-01-07 15:55:57 +08005099 case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC: return "SIM_TRANSMIT_APDU_BASIC";
5100 case RIL_REQUEST_SIM_OPEN_CHANNEL: return "SIM_OPEN_CHANNEL";
5101 case RIL_REQUEST_SIM_CLOSE_CHANNEL: return "SIM_CLOSE_CHANNEL";
5102 case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL: return "SIM_TRANSMIT_APDU_CHANNEL";
Howard Subd82ef12015-04-12 10:25:05 +02005103 case RIL_REQUEST_GET_RADIO_CAPABILITY: return "RIL_REQUEST_GET_RADIO_CAPABILITY";
5104 case RIL_REQUEST_SET_RADIO_CAPABILITY: return "RIL_REQUEST_SET_RADIO_CAPABILITY";
Howard Sue32dbfd2015-01-07 15:55:57 +08005105 case RIL_REQUEST_SET_UICC_SUBSCRIPTION: return "SET_UICC_SUBSCRIPTION";
5106 case RIL_REQUEST_ALLOW_DATA: return "ALLOW_DATA";
5107 case RIL_REQUEST_GET_HARDWARE_CONFIG: return "GET_HARDWARE_CONFIG";
5108 case RIL_REQUEST_SIM_AUTHENTICATION: return "SIM_AUTHENTICATION";
5109 case RIL_REQUEST_GET_DC_RT_INFO: return "GET_DC_RT_INFO";
5110 case RIL_REQUEST_SET_DC_RT_INFO_RATE: return "SET_DC_RT_INFO_RATE";
5111 case RIL_REQUEST_SET_DATA_PROFILE: return "SET_DATA_PROFILE";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005112 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
5113 case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
5114 case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
5115 case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
5116 case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
5117 case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
5118 case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
5119 case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
5120 case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
5121 case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
Howard Subd82ef12015-04-12 10:25:05 +02005122 case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
5123 case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005124 case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
5125 case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
5126 case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
5127 case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
5128 case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FUL";
5129 case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005130 case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
5131 case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
5132 case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_NEW_CDMA_SMS";
5133 case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_NEW_BROADCAST_SMS";
5134 case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
5135 case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
5136 case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
5137 case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
5138 case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
5139 case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
5140 case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
5141 case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONE";
5142 case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
5143 case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED";
5144 case RIL_UNSOL_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
5145 case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
5146 case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
5147 case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED";
Ethan Chend6e30652013-08-04 22:49:56 -07005148 case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST";
Andrew Jiangca4a9a02014-01-18 18:04:08 -05005149 case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return "RESPONSE_IMS_NETWORK_STATE_CHANGED";
Howard Sue32dbfd2015-01-07 15:55:57 +08005150 case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED: return "UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED";
5151 case RIL_UNSOL_SRVCC_STATE_NOTIFY: return "UNSOL_SRVCC_STATE_NOTIFY";
5152 case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: return "HARDWARE_CONFIG_CHANGED";
5153 case RIL_UNSOL_DC_RT_INFO_CHANGED: return "UNSOL_DC_RT_INFO_CHANGED";
Howard Subd82ef12015-04-12 10:25:05 +02005154 case RIL_UNSOL_RADIO_CAPABILITY: return "UNSOL_RADIO_CAPABILITY";
5155 case RIL_UNSOL_ON_SS: return "UNSOL_ON_SS";
5156 case RIL_UNSOL_STK_CC_ALPHA_NOTIFY: return "UNSOL_STK_CC_ALPHA_NOTIFY";
Howard Sue32dbfd2015-01-07 15:55:57 +08005157 case RIL_REQUEST_SHUTDOWN: return "SHUTDOWN";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005158 default: return "<unknown request>";
5159 }
5160}
5161
Howard Sue32dbfd2015-01-07 15:55:57 +08005162const char *
5163rilSocketIdToString(RIL_SOCKET_ID socket_id)
5164{
5165 switch(socket_id) {
5166 case RIL_SOCKET_1:
5167 return "RIL_SOCKET_1";
5168#if (SIM_COUNT >= 2)
5169 case RIL_SOCKET_2:
5170 return "RIL_SOCKET_2";
5171#endif
5172#if (SIM_COUNT >= 3)
5173 case RIL_SOCKET_3:
5174 return "RIL_SOCKET_3";
5175#endif
5176#if (SIM_COUNT >= 4)
5177 case RIL_SOCKET_4:
5178 return "RIL_SOCKET_4";
5179#endif
5180 default:
5181 return "not a valid RIL";
5182 }
5183}
5184
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005185} /* namespace android */