blob: 2bb7684caca7def64e88fd80b5e9ff9da8f0cad6 [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>
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020021#include <telephony/ril.h>
22#include <telephony/ril_cdma_sms.h>
23#include <cutils/sockets.h>
24#include <cutils/jstring.h>
Andrew Jiangca4a9a02014-01-18 18:04:08 -050025#include <telephony/record_stream.h>
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020026#include <utils/Log.h>
27#include <utils/SystemClock.h>
28#include <pthread.h>
29#include <binder/Parcel.h>
30#include <cutils/jstring.h>
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020031#include <sys/types.h>
XpLoDWilDba5c6a32013-07-27 21:12:19 +020032#include <sys/limits.h>
Sanket Padawe9343e872016-01-11 12:45:43 -080033#include <sys/system_properties.h>
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020034#include <pwd.h>
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020035#include <stdio.h>
36#include <stdlib.h>
37#include <stdarg.h>
38#include <string.h>
39#include <unistd.h>
40#include <fcntl.h>
41#include <time.h>
42#include <errno.h>
43#include <assert.h>
44#include <ctype.h>
45#include <alloca.h>
46#include <sys/un.h>
47#include <assert.h>
48#include <netinet/in.h>
49#include <cutils/properties.h>
Dheeraj Shettycc231012014-07-02 21:27:57 +020050#include <RilSapSocket.h>
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020051
Dheeraj Shettycc231012014-07-02 21:27:57 +020052extern "C" void
53RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020054namespace android {
55
56#define PHONE_PROCESS "radio"
Dheeraj Shettycc231012014-07-02 21:27:57 +020057#define BLUETOOTH_PROCESS "bluetooth"
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020058
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
Nathan Haroldd6306fa2015-07-28 14:54:58 -070068#define ANDROID_WAKE_LOCK_SECS 0
69#define ANDROID_WAKE_LOCK_USECS 200000
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020070
71#define PROPERTY_RIL_IMPL "gsm.version.ril-impl"
72
73// match with constant in RIL.java
74#define MAX_COMMAND_BYTES (8 * 1024)
75
76// Basically: memset buffers that the client library
77// shouldn't be using anymore in an attempt to find
78// memory usage issues sooner.
79#define MEMSET_FREED 1
80
81#define NUM_ELEMS(a) (sizeof (a) / sizeof (a)[0])
82
83#define MIN(a,b) ((a)<(b) ? (a) : (b))
84
85/* Constants for response types */
86#define RESPONSE_SOLICITED 0
87#define RESPONSE_UNSOLICITED 1
88
89/* Negative values for private RIL errno's */
90#define RIL_ERRNO_INVALID_RESPONSE -1
91
92// request, response, and unsolicited msg print macro
93#define PRINTBUF_SIZE 8096
94
Robert Greenwaltbc29c432015-04-29 16:57:39 -070095// Enable verbose logging
96#define VDBG 0
97
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020098// Enable RILC log
99#define RILC_LOG 0
100
101#if RILC_LOG
102 #define startRequest sprintf(printBuf, "(")
103 #define closeRequest sprintf(printBuf, "%s)", printBuf)
forkbombe0568e12015-11-23 18:37:37 +1100104 #define printRequest(token, req) \
105 RLOGD("[%04d]> %s %s", token, requestToString(req), printBuf)
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200106
107 #define startResponse sprintf(printBuf, "%s {", printBuf)
108 #define closeResponse sprintf(printBuf, "%s}", printBuf)
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200109 #define printResponse RLOGD("%s", printBuf)
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200110
111 #define clearPrintBuf printBuf[0] = 0
112 #define removeLastChar printBuf[strlen(printBuf)-1] = 0
Ajay Nambi323c8822015-08-05 14:53:50 +0530113 #define appendPrintBuf(x...) snprintf(printBuf, PRINTBUF_SIZE, x)
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200114#else
115 #define startRequest
116 #define closeRequest
117 #define printRequest(token, req)
118 #define startResponse
119 #define closeResponse
120 #define printResponse
121 #define clearPrintBuf
122 #define removeLastChar
123 #define appendPrintBuf(x...)
124#endif
125
126enum WakeType {DONT_WAKE, WAKE_PARTIAL};
127
128typedef struct {
129 int requestNumber;
130 void (*dispatchFunction) (Parcel &p, struct RequestInfo *pRI);
131 int(*responseFunction) (Parcel &p, void *response, size_t responselen);
132} CommandInfo;
133
134typedef struct {
135 int requestNumber;
136 int (*responseFunction) (Parcel &p, void *response, size_t responselen);
137 WakeType wakeType;
138} UnsolResponseInfo;
139
140typedef struct RequestInfo {
141 int32_t token; //this is not RIL_Token
142 CommandInfo *pCI;
143 struct RequestInfo *p_next;
144 char cancelled;
145 char local; // responses to local commands do not go back to command process
Howard Sue32dbfd2015-01-07 15:55:57 +0800146 RIL_SOCKET_ID socket_id;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200147} RequestInfo;
148
149typedef struct UserCallbackInfo {
150 RIL_TimedCallback p_callback;
151 void *userParam;
152 struct ril_event event;
153 struct UserCallbackInfo *p_next;
154} UserCallbackInfo;
155
Howard Sue32dbfd2015-01-07 15:55:57 +0800156extern "C" const char * requestToString(int request);
157extern "C" const char * failCauseToString(RIL_Errno);
158extern "C" const char * callStateToString(RIL_CallState);
159extern "C" const char * radioStateToString(RIL_RadioState);
160extern "C" const char * rilSocketIdToString(RIL_SOCKET_ID socket_id);
161
162extern "C"
163char rild[MAX_SOCKET_NAME_LENGTH] = SOCKET_NAME_RIL;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200164
Howard Subd82ef12015-04-12 10:25:05 +0200165#define RIL_VENDOR_COMMANDS_OFFSET 10000
166
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200167/*******************************************************************/
168
169RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL};
170static int s_registerCalled = 0;
171
172static pthread_t s_tid_dispatch;
173static pthread_t s_tid_reader;
174static int s_started = 0;
175
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200176static int s_fdDebug = -1;
Howard Sue32dbfd2015-01-07 15:55:57 +0800177static int s_fdDebug_socket2 = -1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200178
179static int s_fdWakeupRead;
180static int s_fdWakeupWrite;
181
182static struct ril_event s_commands_event;
183static struct ril_event s_wakeupfd_event;
184static struct ril_event s_listen_event;
Howard Sue32dbfd2015-01-07 15:55:57 +0800185static SocketListenParam s_ril_param_socket;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200186
187static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER;
188static pthread_mutex_t s_writeMutex = PTHREAD_MUTEX_INITIALIZER;
Howard Sue32dbfd2015-01-07 15:55:57 +0800189static RequestInfo *s_pendingRequests = NULL;
190
191#if (SIM_COUNT >= 2)
192static struct ril_event s_commands_event_socket2;
193static struct ril_event s_listen_event_socket2;
194static SocketListenParam s_ril_param_socket2;
195
196static pthread_mutex_t s_pendingRequestsMutex_socket2 = PTHREAD_MUTEX_INITIALIZER;
197static pthread_mutex_t s_writeMutex_socket2 = PTHREAD_MUTEX_INITIALIZER;
198static RequestInfo *s_pendingRequests_socket2 = NULL;
199#endif
200
201#if (SIM_COUNT >= 3)
202static struct ril_event s_commands_event_socket3;
203static struct ril_event s_listen_event_socket3;
204static SocketListenParam s_ril_param_socket3;
205
206static pthread_mutex_t s_pendingRequestsMutex_socket3 = PTHREAD_MUTEX_INITIALIZER;
207static pthread_mutex_t s_writeMutex_socket3 = PTHREAD_MUTEX_INITIALIZER;
208static RequestInfo *s_pendingRequests_socket3 = NULL;
209#endif
210
211#if (SIM_COUNT >= 4)
212static struct ril_event s_commands_event_socket4;
213static struct ril_event s_listen_event_socket4;
214static SocketListenParam s_ril_param_socket4;
215
216static pthread_mutex_t s_pendingRequestsMutex_socket4 = PTHREAD_MUTEX_INITIALIZER;
217static pthread_mutex_t s_writeMutex_socket4 = PTHREAD_MUTEX_INITIALIZER;
218static RequestInfo *s_pendingRequests_socket4 = NULL;
219#endif
220
221static struct ril_event s_wake_timeout_event;
222static struct ril_event s_debug_event;
223
Howard Subd82ef12015-04-12 10:25:05 +0200224
Nathan Haroldd6306fa2015-07-28 14:54:58 -0700225static const struct timeval TIMEVAL_WAKE_TIMEOUT = {ANDROID_WAKE_LOCK_SECS,ANDROID_WAKE_LOCK_USECS};
Howard Sue32dbfd2015-01-07 15:55:57 +0800226
Howard Subd82ef12015-04-12 10:25:05 +0200227
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200228static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
229static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER;
230
231static pthread_mutex_t s_dispatchMutex = PTHREAD_MUTEX_INITIALIZER;
232static pthread_cond_t s_dispatchCond = PTHREAD_COND_INITIALIZER;
233
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200234static RequestInfo *s_toDispatchHead = NULL;
235static RequestInfo *s_toDispatchTail = NULL;
236
237static UserCallbackInfo *s_last_wake_timeout_info = NULL;
238
239static void *s_lastNITZTimeData = NULL;
240static size_t s_lastNITZTimeDataSize;
241
242#if RILC_LOG
243 static char printBuf[PRINTBUF_SIZE];
244#endif
245
246/*******************************************************************/
Howard Sue32dbfd2015-01-07 15:55:57 +0800247static int sendResponse (Parcel &p, RIL_SOCKET_ID socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200248
249static void dispatchVoid (Parcel& p, RequestInfo *pRI);
250static void dispatchString (Parcel& p, RequestInfo *pRI);
251static void dispatchStrings (Parcel& p, RequestInfo *pRI);
252static void dispatchInts (Parcel& p, RequestInfo *pRI);
253static void dispatchDial (Parcel& p, RequestInfo *pRI);
254static void dispatchSIM_IO (Parcel& p, RequestInfo *pRI);
Howard Sue32dbfd2015-01-07 15:55:57 +0800255static void dispatchSIM_APDU (Parcel& p, RequestInfo *pRI);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200256static void dispatchCallForward(Parcel& p, RequestInfo *pRI);
257static void dispatchRaw(Parcel& p, RequestInfo *pRI);
258static void dispatchSmsWrite (Parcel &p, RequestInfo *pRI);
259static void dispatchDataCall (Parcel& p, RequestInfo *pRI);
260static void dispatchVoiceRadioTech (Parcel& p, RequestInfo *pRI);
Andrew Jiangca4a9a02014-01-18 18:04:08 -0500261static void dispatchSetInitialAttachApn (Parcel& p, RequestInfo *pRI);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200262static void dispatchCdmaSubscriptionSource (Parcel& p, RequestInfo *pRI);
263
264static void dispatchCdmaSms(Parcel &p, RequestInfo *pRI);
Andrew Jiangca4a9a02014-01-18 18:04:08 -0500265static void dispatchImsSms(Parcel &p, RequestInfo *pRI);
266static void dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef);
267static void dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200268static void dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI);
269static void dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI);
270static void dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI);
271static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI);
Howard Sue32dbfd2015-01-07 15:55:57 +0800272static void dispatchNVReadItem(Parcel &p, RequestInfo *pRI);
273static void dispatchNVWriteItem(Parcel &p, RequestInfo *pRI);
274static void dispatchUiccSubscripton(Parcel &p, RequestInfo *pRI);
275static void dispatchSimAuthentication(Parcel &p, RequestInfo *pRI);
276static void dispatchDataProfile(Parcel &p, RequestInfo *pRI);
Howard Subd82ef12015-04-12 10:25:05 +0200277static void dispatchRadioCapability(Parcel &p, RequestInfo *pRI);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200278static int responseInts(Parcel &p, void *response, size_t responselen);
Daniel Hillenbrandd0b84162015-04-12 11:53:23 +0200279static int responseIntsGetPreferredNetworkType(Parcel &p, void *response, size_t responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200280static int responseStrings(Parcel &p, void *response, size_t responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200281static int responseString(Parcel &p, void *response, size_t responselen);
282static int responseVoid(Parcel &p, void *response, size_t responselen);
283static int responseCallList(Parcel &p, void *response, size_t responselen);
284static int responseSMS(Parcel &p, void *response, size_t responselen);
285static int responseSIM_IO(Parcel &p, void *response, size_t responselen);
286static int responseCallForwards(Parcel &p, void *response, size_t responselen);
287static int responseDataCallList(Parcel &p, void *response, size_t responselen);
288static int responseSetupDataCall(Parcel &p, void *response, size_t responselen);
289static int responseRaw(Parcel &p, void *response, size_t responselen);
290static int responseSsn(Parcel &p, void *response, size_t responselen);
291static int responseSimStatus(Parcel &p, void *response, size_t responselen);
292static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen);
293static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen);
294static int responseCdmaSms(Parcel &p, void *response, size_t responselen);
295static int responseCellList(Parcel &p, void *response, size_t responselen);
296static int responseCdmaInformationRecords(Parcel &p,void *response, size_t responselen);
297static int responseRilSignalStrength(Parcel &p,void *response, size_t responselen);
298static int responseCallRing(Parcel &p, void *response, size_t responselen);
299static int responseCdmaSignalInfoRecord(Parcel &p,void *response, size_t responselen);
300static int responseCdmaCallWaiting(Parcel &p,void *response, size_t responselen);
301static int responseSimRefresh(Parcel &p, void *response, size_t responselen);
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200302static int responseCellInfoList(Parcel &p, void *response, size_t responselen);
Howard Sue32dbfd2015-01-07 15:55:57 +0800303static int responseHardwareConfig(Parcel &p, void *response, size_t responselen);
304static int responseDcRtInfo(Parcel &p, void *response, size_t responselen);
Howard Subd82ef12015-04-12 10:25:05 +0200305static int responseRadioCapability(Parcel &p, void *response, size_t responselen);
306static int responseSSData(Parcel &p, void *response, size_t responselen);
fenglu9bdede02015-04-14 14:53:55 -0700307static int responseLceStatus(Parcel &p, void *response, size_t responselen);
308static int responseLceData(Parcel &p, void *response, size_t responselen);
Prerepa Viswanadham8e755592015-05-28 00:37:32 -0700309static int responseActivityData(Parcel &p, void *response, size_t responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200310
311static int decodeVoiceRadioTechnology (RIL_RadioState radioState);
312static int decodeCdmaSubscriptionSource (RIL_RadioState radioState);
Howard Subd82ef12015-04-12 10:25:05 +0200313static RIL_RadioState processRadioState(RIL_RadioState newRadioState);
314
315static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200316
Sanket Padawe9343e872016-01-11 12:45:43 -0800317static bool isDebuggable();
318
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200319#ifdef RIL_SHLIB
Howard Sue32dbfd2015-01-07 15:55:57 +0800320#if defined(ANDROID_MULTI_SIM)
Andreas Schneider47b2d962015-04-13 22:54:49 +0200321extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
Howard Sue32dbfd2015-01-07 15:55:57 +0800322 size_t datalen, RIL_SOCKET_ID socket_id);
323#else
Andreas Schneider47b2d962015-04-13 22:54:49 +0200324extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200325 size_t datalen);
326#endif
Howard Sue32dbfd2015-01-07 15:55:57 +0800327#endif
328
329#if defined(ANDROID_MULTI_SIM)
330#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c), (d))
331#define CALL_ONREQUEST(a, b, c, d, e) s_callbacks.onRequest((a), (b), (c), (d), (e))
332#define CALL_ONSTATEREQUEST(a) s_callbacks.onStateRequest(a)
333#else
334#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c))
335#define CALL_ONREQUEST(a, b, c, d, e) s_callbacks.onRequest((a), (b), (c), (d))
336#define CALL_ONSTATEREQUEST(a) s_callbacks.onStateRequest()
337#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200338
339static UserCallbackInfo * internalRequestTimedCallback
340 (RIL_TimedCallback callback, void *param,
341 const struct timeval *relativeTime);
342
343/** Index == requestNumber */
344static CommandInfo s_commands[] = {
345#include "ril_commands.h"
346};
347
348static UnsolResponseInfo s_unsolResponses[] = {
349#include "ril_unsol_commands.h"
350};
351
Christopher N. Hessec694ff02016-03-27 21:04:38 +0200352static CommandInfo s_commands_v[] = {
353#include <telephony/ril_commands_vendor.h>
354};
355
Howard Subd82ef12015-04-12 10:25:05 +0200356static UnsolResponseInfo s_unsolResponses_v[] = {
Christopher N. Hessec694ff02016-03-27 21:04:38 +0200357#include <telephony/ril_unsol_commands_vendor.h>
Howard Subd82ef12015-04-12 10:25:05 +0200358};
359
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200360/* For older RILs that do not support new commands RIL_REQUEST_VOICE_RADIO_TECH and
361 RIL_UNSOL_VOICE_RADIO_TECH_CHANGED messages, decode the voice radio tech from
362 radio state message and store it. Every time there is a change in Radio State
363 check to see if voice radio tech changes and notify telephony
364 */
365int voiceRadioTech = -1;
366
367/* For older RILs that do not support new commands RIL_REQUEST_GET_CDMA_SUBSCRIPTION_SOURCE
368 and RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED messages, decode the subscription
369 source from radio state and store it. Every time there is a change in Radio State
370 check to see if subscription source changed and notify telephony
371 */
372int cdmaSubscriptionSource = -1;
373
374/* For older RILs that do not send RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, decode the
375 SIM/RUIM state from radio state and store it. Every time there is a change in Radio State,
376 check to see if SIM/RUIM status changed and notify telephony
377 */
378int simRuimStatus = -1;
379
Howard Sue32dbfd2015-01-07 15:55:57 +0800380static char * RIL_getRilSocketName() {
381 return rild;
382}
383
384extern "C"
Dheeraj Shettycc231012014-07-02 21:27:57 +0200385void RIL_setRilSocketName(const char * s) {
Howard Sue32dbfd2015-01-07 15:55:57 +0800386 strncpy(rild, s, MAX_SOCKET_NAME_LENGTH);
387}
388
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200389static char *
390strdupReadString(Parcel &p) {
391 size_t stringlen;
392 const char16_t *s16;
393
394 s16 = p.readString16Inplace(&stringlen);
395
396 return strndup16to8(s16, stringlen);
397}
398
Howard Subd82ef12015-04-12 10:25:05 +0200399static status_t
400readStringFromParcelInplace(Parcel &p, char *str, size_t maxLen) {
401 size_t s16Len;
402 const char16_t *s16;
403
404 s16 = p.readString16Inplace(&s16Len);
405 if (s16 == NULL) {
406 return NO_MEMORY;
407 }
408 size_t strLen = strnlen16to8(s16, s16Len);
409 if ((strLen + 1) > maxLen) {
410 return NO_MEMORY;
411 }
412 if (strncpy16to8(str, s16, strLen) == NULL) {
413 return NO_MEMORY;
414 } else {
415 return NO_ERROR;
416 }
417}
418
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200419static void writeStringToParcel(Parcel &p, const char *s) {
420 char16_t *s16;
421 size_t s16_len;
422 s16 = strdup8to16(s, &s16_len);
423 p.writeString16(s16, s16_len);
424 free(s16);
425}
426
427
428static void
429memsetString (char *s) {
430 if (s != NULL) {
431 memset (s, 0, strlen(s));
432 }
433}
434
435void nullParcelReleaseFunction (const uint8_t* data, size_t dataSize,
436 const size_t* objects, size_t objectsSize,
437 void* cookie) {
438 // do nothing -- the data reference lives longer than the Parcel object
439}
440
441/**
442 * To be called from dispatch thread
443 * Issue a single local request, ensuring that the response
444 * is not sent back up to the command process
445 */
446static void
Howard Sue32dbfd2015-01-07 15:55:57 +0800447issueLocalRequest(int request, void *data, int len, RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200448 RequestInfo *pRI;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200449 int ret;
Howard Sue32dbfd2015-01-07 15:55:57 +0800450 /* Hook for current context */
451 /* pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
452 pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
453 /* pendingRequestsHook refer to &s_pendingRequests */
454 RequestInfo** pendingRequestsHook = &s_pendingRequests;
455
456#if (SIM_COUNT == 2)
457 if (socket_id == RIL_SOCKET_2) {
458 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
459 pendingRequestsHook = &s_pendingRequests_socket2;
460 }
461#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200462
463 pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
464
465 pRI->local = 1;
466 pRI->token = 0xffffffff; // token is not used in this context
467
Howard Subd82ef12015-04-12 10:25:05 +0200468 /* Check vendor commands */
469 if (request > RIL_VENDOR_COMMANDS_OFFSET) {
470 pRI->pCI = &(s_commands_v[request - RIL_VENDOR_COMMANDS_OFFSET]);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200471 } else {
472 pRI->pCI = &(s_commands[request]);
473 }
Howard Sue32dbfd2015-01-07 15:55:57 +0800474 pRI->socket_id = socket_id;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200475
Howard Sue32dbfd2015-01-07 15:55:57 +0800476 ret = pthread_mutex_lock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200477 assert (ret == 0);
478
Howard Sue32dbfd2015-01-07 15:55:57 +0800479 pRI->p_next = *pendingRequestsHook;
480 *pendingRequestsHook = pRI;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200481
Howard Sue32dbfd2015-01-07 15:55:57 +0800482 ret = pthread_mutex_unlock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200483 assert (ret == 0);
484
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200485 RLOGD("C[locl]> %s", requestToString(request));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200486
Howard Sue32dbfd2015-01-07 15:55:57 +0800487 CALL_ONREQUEST(request, data, len, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200488}
489
Howard Subd82ef12015-04-12 10:25:05 +0200490
491
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200492static int
Howard Sue32dbfd2015-01-07 15:55:57 +0800493processCommandBuffer(void *buffer, size_t buflen, RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200494 Parcel p;
495 status_t status;
496 int32_t request;
497 int32_t token;
498 RequestInfo *pRI;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200499 int ret;
Howard Sue32dbfd2015-01-07 15:55:57 +0800500 /* Hook for current context */
501 /* pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
502 pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
503 /* pendingRequestsHook refer to &s_pendingRequests */
504 RequestInfo** pendingRequestsHook = &s_pendingRequests;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200505
506 p.setData((uint8_t *) buffer, buflen);
507
508 // status checked at end
509 status = p.readInt32(&request);
510 status = p.readInt32 (&token);
511
Howard Sue32dbfd2015-01-07 15:55:57 +0800512#if (SIM_COUNT >= 2)
513 if (socket_id == RIL_SOCKET_2) {
514 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
515 pendingRequestsHook = &s_pendingRequests_socket2;
516 }
517#if (SIM_COUNT >= 3)
518 else if (socket_id == RIL_SOCKET_3) {
519 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
520 pendingRequestsHook = &s_pendingRequests_socket3;
521 }
522#endif
523#if (SIM_COUNT >= 4)
524 else if (socket_id == RIL_SOCKET_4) {
525 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
526 pendingRequestsHook = &s_pendingRequests_socket4;
527 }
528#endif
529#endif
530
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200531 if (status != NO_ERROR) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200532 RLOGE("invalid request block");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200533 return 0;
534 }
535
Howard Subd82ef12015-04-12 10:25:05 +0200536 CommandInfo *pCI = NULL;
537 if (request > RIL_VENDOR_COMMANDS_OFFSET) {
538 int index = request - RIL_VENDOR_COMMANDS_OFFSET;
539 RLOGD("processCommandBuffer: samsung request=%d, index=%d",
540 request, index);
541 if (index < (int32_t)NUM_ELEMS(s_commands_v))
542 pCI = &(s_commands_v[index]);
543 } else {
544 if (request < (int32_t)NUM_ELEMS(s_commands))
545 pCI = &(s_commands[request]);
546 }
Howard Sue32dbfd2015-01-07 15:55:57 +0800547
Howard Subd82ef12015-04-12 10:25:05 +0200548 if (pCI == NULL) {
549 Parcel pErr;
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200550 RLOGE("unsupported request code %d token %d", request, token);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200551 // FIXME this should perhaps return a response
Howard Sue32dbfd2015-01-07 15:55:57 +0800552 pErr.writeInt32 (RESPONSE_SOLICITED);
553 pErr.writeInt32 (token);
554 pErr.writeInt32 (RIL_E_GENERIC_FAILURE);
555
556 sendResponse(pErr, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200557 return 0;
558 }
559
560 pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
561
562 pRI->token = token;
Howard Subd82ef12015-04-12 10:25:05 +0200563 pRI->pCI = pCI;
Howard Sue32dbfd2015-01-07 15:55:57 +0800564 pRI->socket_id = socket_id;
565
566 ret = pthread_mutex_lock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200567 assert (ret == 0);
568
Howard Sue32dbfd2015-01-07 15:55:57 +0800569 pRI->p_next = *pendingRequestsHook;
570 *pendingRequestsHook = pRI;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200571
Howard Sue32dbfd2015-01-07 15:55:57 +0800572 ret = pthread_mutex_unlock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200573 assert (ret == 0);
574
575/* sLastDispatchedToken = token; */
576
577 pRI->pCI->dispatchFunction(p, pRI);
578
579 return 0;
580}
581
582static void
583invalidCommandBlock (RequestInfo *pRI) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200584 RLOGE("invalid command block for token %d request %s",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200585 pRI->token, requestToString(pRI->pCI->requestNumber));
586}
587
588/** Callee expects NULL */
589static void
590dispatchVoid (Parcel& p, RequestInfo *pRI) {
591 clearPrintBuf;
592 printRequest(pRI->token, pRI->pCI->requestNumber);
Howard Sue32dbfd2015-01-07 15:55:57 +0800593 CALL_ONREQUEST(pRI->pCI->requestNumber, NULL, 0, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200594}
595
596/** Callee expects const char * */
597static void
598dispatchString (Parcel& p, RequestInfo *pRI) {
599 status_t status;
600 size_t datalen;
601 size_t stringlen;
602 char *string8 = NULL;
603
604 string8 = strdupReadString(p);
605
606 startRequest;
607 appendPrintBuf("%s%s", printBuf, string8);
608 closeRequest;
609 printRequest(pRI->token, pRI->pCI->requestNumber);
610
Howard Sue32dbfd2015-01-07 15:55:57 +0800611 CALL_ONREQUEST(pRI->pCI->requestNumber, string8,
612 sizeof(char *), pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200613
614#ifdef MEMSET_FREED
615 memsetString(string8);
616#endif
617
618 free(string8);
619 return;
620invalid:
621 invalidCommandBlock(pRI);
622 return;
623}
624
625/** Callee expects const char ** */
626static void
627dispatchStrings (Parcel &p, RequestInfo *pRI) {
628 int32_t countStrings;
629 status_t status;
630 size_t datalen;
631 char **pStrings;
632
633 status = p.readInt32 (&countStrings);
634
635 if (status != NO_ERROR) {
636 goto invalid;
637 }
638
639 startRequest;
640 if (countStrings == 0) {
641 // just some non-null pointer
642 pStrings = (char **)alloca(sizeof(char *));
643 datalen = 0;
644 } else if (((int)countStrings) == -1) {
645 pStrings = NULL;
646 datalen = 0;
647 } else {
648 datalen = sizeof(char *) * countStrings;
649
650 pStrings = (char **)alloca(datalen);
651
652 for (int i = 0 ; i < countStrings ; i++) {
653 pStrings[i] = strdupReadString(p);
654 appendPrintBuf("%s%s,", printBuf, pStrings[i]);
655 }
656 }
657 removeLastChar;
658 closeRequest;
659 printRequest(pRI->token, pRI->pCI->requestNumber);
660
Howard Sue32dbfd2015-01-07 15:55:57 +0800661 CALL_ONREQUEST(pRI->pCI->requestNumber, pStrings, datalen, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200662
663 if (pStrings != NULL) {
664 for (int i = 0 ; i < countStrings ; i++) {
665#ifdef MEMSET_FREED
666 memsetString (pStrings[i]);
667#endif
668 free(pStrings[i]);
669 }
670
671#ifdef MEMSET_FREED
672 memset(pStrings, 0, datalen);
673#endif
674 }
675
676 return;
677invalid:
678 invalidCommandBlock(pRI);
679 return;
680}
681
682/** Callee expects const int * */
683static void
684dispatchInts (Parcel &p, RequestInfo *pRI) {
685 int32_t count;
686 status_t status;
687 size_t datalen;
688 int *pInts;
689
690 status = p.readInt32 (&count);
691
692 if (status != NO_ERROR || count == 0) {
693 goto invalid;
694 }
695
696 datalen = sizeof(int) * count;
697 pInts = (int *)alloca(datalen);
698
699 startRequest;
700 for (int i = 0 ; i < count ; i++) {
701 int32_t t;
702
703 status = p.readInt32(&t);
704 pInts[i] = (int)t;
705 appendPrintBuf("%s%d,", printBuf, t);
706
707 if (status != NO_ERROR) {
708 goto invalid;
709 }
710 }
711 removeLastChar;
712 closeRequest;
713 printRequest(pRI->token, pRI->pCI->requestNumber);
714
Howard Sue32dbfd2015-01-07 15:55:57 +0800715 CALL_ONREQUEST(pRI->pCI->requestNumber, const_cast<int *>(pInts),
716 datalen, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200717
718#ifdef MEMSET_FREED
719 memset(pInts, 0, datalen);
720#endif
721
722 return;
723invalid:
724 invalidCommandBlock(pRI);
725 return;
726}
727
728
729/**
730 * Callee expects const RIL_SMS_WriteArgs *
731 * Payload is:
732 * int32_t status
733 * String pdu
734 */
735static void
736dispatchSmsWrite (Parcel &p, RequestInfo *pRI) {
737 RIL_SMS_WriteArgs args;
738 int32_t t;
739 status_t status;
740
Mark Salyzyn961fd022015-04-09 07:18:35 -0700741 RLOGD("dispatchSmsWrite");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200742 memset (&args, 0, sizeof(args));
743
744 status = p.readInt32(&t);
745 args.status = (int)t;
746
747 args.pdu = strdupReadString(p);
748
749 if (status != NO_ERROR || args.pdu == NULL) {
750 goto invalid;
751 }
752
753 args.smsc = strdupReadString(p);
754
755 startRequest;
756 appendPrintBuf("%s%d,%s,smsc=%s", printBuf, args.status,
757 (char*)args.pdu, (char*)args.smsc);
758 closeRequest;
759 printRequest(pRI->token, pRI->pCI->requestNumber);
760
Howard Sue32dbfd2015-01-07 15:55:57 +0800761 CALL_ONREQUEST(pRI->pCI->requestNumber, &args, sizeof(args), pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200762
763#ifdef MEMSET_FREED
764 memsetString (args.pdu);
765#endif
766
767 free (args.pdu);
768
769#ifdef MEMSET_FREED
770 memset(&args, 0, sizeof(args));
771#endif
772
773 return;
774invalid:
775 invalidCommandBlock(pRI);
776 return;
777}
778
779/**
780 * Callee expects const RIL_Dial *
781 * Payload is:
782 * String address
783 * int32_t clir
784 */
785static void
786dispatchDial (Parcel &p, RequestInfo *pRI) {
787 RIL_Dial dial;
788 RIL_UUS_Info uusInfo;
789 int32_t sizeOfDial;
790 int32_t t;
791 int32_t uusPresent;
Christopher N. Hesse621e63e2016-02-22 21:57:39 +0100792#ifdef SAMSUNG_NEXT_GEN_MODEM
Andreas Schneider29472682015-01-01 19:00:04 +0100793 char *csv;
794#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200795 status_t status;
796
Mark Salyzyn961fd022015-04-09 07:18:35 -0700797 RLOGD("dispatchDial");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200798 memset (&dial, 0, sizeof(dial));
799
800 dial.address = strdupReadString(p);
801
802 status = p.readInt32(&t);
803 dial.clir = (int)t;
804
805 if (status != NO_ERROR || dial.address == NULL) {
806 goto invalid;
807 }
808
Christopher N. Hesse621e63e2016-02-22 21:57:39 +0100809#ifdef SAMSUNG_NEXT_GEN_MODEM
Andreas Schneider29472682015-01-01 19:00:04 +0100810 /* CallDetails.call_type */
811 status = p.readInt32(&t);
812 if (status != NO_ERROR) {
813 goto invalid;
814 }
815 /* CallDetails.call_domain */
816 p.readInt32(&t);
817 if (status != NO_ERROR) {
818 goto invalid;
819 }
820 /* CallDetails.getCsvFromExtra */
821 csv = strdupReadString(p);
822 if (csv == NULL) {
823 goto invalid;
824 }
825 free(csv);
826#endif
827
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200828 if (s_callbacks.version < 3) { // Remove when partners upgrade to version 3
829 uusPresent = 0;
830 sizeOfDial = sizeof(dial) - sizeof(RIL_UUS_Info *);
831 } else {
832 status = p.readInt32(&uusPresent);
833
834 if (status != NO_ERROR) {
835 goto invalid;
836 }
837
838 if (uusPresent == 0) {
Christopher N. Hesse621e63e2016-02-22 21:57:39 +0100839#if defined(MODEM_TYPE_XMM6262) || defined(SAMSUNG_NEXT_GEN_MODEM)
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200840 dial.uusInfo = NULL;
Andreas Schneiderf68609b2015-04-07 19:01:34 +0200841#elif defined(MODEM_TYPE_XMM6260)
Howard Sue32dbfd2015-01-07 15:55:57 +0800842 /* Samsung hack */
843 memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
844 uusInfo.uusType = (RIL_UUS_Type) 0;
845 uusInfo.uusDcs = (RIL_UUS_DCS) 0;
846 uusInfo.uusData = NULL;
847 uusInfo.uusLength = 0;
848 dial.uusInfo = &uusInfo;
849#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200850 } else {
851 int32_t len;
852
853 memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
854
855 status = p.readInt32(&t);
856 uusInfo.uusType = (RIL_UUS_Type) t;
857
858 status = p.readInt32(&t);
859 uusInfo.uusDcs = (RIL_UUS_DCS) t;
860
861 status = p.readInt32(&len);
862 if (status != NO_ERROR) {
863 goto invalid;
864 }
865
866 // The java code writes -1 for null arrays
867 if (((int) len) == -1) {
868 uusInfo.uusData = NULL;
869 len = 0;
870 } else {
871 uusInfo.uusData = (char*) p.readInplace(len);
872 }
873
874 uusInfo.uusLength = len;
875 dial.uusInfo = &uusInfo;
876 }
877 sizeOfDial = sizeof(dial);
878 }
879
880 startRequest;
881 appendPrintBuf("%snum=%s,clir=%d", printBuf, dial.address, dial.clir);
882 if (uusPresent) {
883 appendPrintBuf("%s,uusType=%d,uusDcs=%d,uusLen=%d", printBuf,
884 dial.uusInfo->uusType, dial.uusInfo->uusDcs,
885 dial.uusInfo->uusLength);
886 }
887 closeRequest;
888 printRequest(pRI->token, pRI->pCI->requestNumber);
889
Howard Sue32dbfd2015-01-07 15:55:57 +0800890 CALL_ONREQUEST(pRI->pCI->requestNumber, &dial, sizeOfDial, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200891
892#ifdef MEMSET_FREED
893 memsetString (dial.address);
894#endif
895
896 free (dial.address);
897
898#ifdef MEMSET_FREED
899 memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
900 memset(&dial, 0, sizeof(dial));
901#endif
902
903 return;
904invalid:
905 invalidCommandBlock(pRI);
906 return;
907}
908
909/**
910 * Callee expects const RIL_SIM_IO *
911 * Payload is:
912 * int32_t command
913 * int32_t fileid
914 * String path
915 * int32_t p1, p2, p3
916 * String data
917 * String pin2
918 * String aidPtr
919 */
920static void
921dispatchSIM_IO (Parcel &p, RequestInfo *pRI) {
922 union RIL_SIM_IO {
923 RIL_SIM_IO_v6 v6;
924 RIL_SIM_IO_v5 v5;
925 } simIO;
926
927 int32_t t;
928 int size;
929 status_t status;
930
Robert Greenwaltbc29c432015-04-29 16:57:39 -0700931#if VDBG
Mark Salyzyn961fd022015-04-09 07:18:35 -0700932 RLOGD("dispatchSIM_IO");
Robert Greenwaltbc29c432015-04-29 16:57:39 -0700933#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200934 memset (&simIO, 0, sizeof(simIO));
935
936 // note we only check status at the end
937
938 status = p.readInt32(&t);
939 simIO.v6.command = (int)t;
940
941 status = p.readInt32(&t);
942 simIO.v6.fileid = (int)t;
943
944 simIO.v6.path = strdupReadString(p);
945
946 status = p.readInt32(&t);
947 simIO.v6.p1 = (int)t;
948
949 status = p.readInt32(&t);
950 simIO.v6.p2 = (int)t;
951
952 status = p.readInt32(&t);
953 simIO.v6.p3 = (int)t;
954
955 simIO.v6.data = strdupReadString(p);
956 simIO.v6.pin2 = strdupReadString(p);
957 simIO.v6.aidPtr = strdupReadString(p);
958
959 startRequest;
960 appendPrintBuf("%scmd=0x%X,efid=0x%X,path=%s,%d,%d,%d,%s,pin2=%s,aid=%s", printBuf,
961 simIO.v6.command, simIO.v6.fileid, (char*)simIO.v6.path,
962 simIO.v6.p1, simIO.v6.p2, simIO.v6.p3,
963 (char*)simIO.v6.data, (char*)simIO.v6.pin2, simIO.v6.aidPtr);
964 closeRequest;
965 printRequest(pRI->token, pRI->pCI->requestNumber);
966
967 if (status != NO_ERROR) {
968 goto invalid;
969 }
970
971 size = (s_callbacks.version < 6) ? sizeof(simIO.v5) : sizeof(simIO.v6);
Howard Sue32dbfd2015-01-07 15:55:57 +0800972 CALL_ONREQUEST(pRI->pCI->requestNumber, &simIO, size, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200973
974#ifdef MEMSET_FREED
975 memsetString (simIO.v6.path);
976 memsetString (simIO.v6.data);
977 memsetString (simIO.v6.pin2);
978 memsetString (simIO.v6.aidPtr);
979#endif
980
981 free (simIO.v6.path);
982 free (simIO.v6.data);
983 free (simIO.v6.pin2);
984 free (simIO.v6.aidPtr);
985
986#ifdef MEMSET_FREED
987 memset(&simIO, 0, sizeof(simIO));
988#endif
989
990 return;
991invalid:
992 invalidCommandBlock(pRI);
993 return;
994}
995
996/**
Howard Sue32dbfd2015-01-07 15:55:57 +0800997 * Callee expects const RIL_SIM_APDU *
998 * Payload is:
999 * int32_t sessionid
1000 * int32_t cla
1001 * int32_t instruction
1002 * int32_t p1, p2, p3
1003 * String data
1004 */
1005static void
1006dispatchSIM_APDU (Parcel &p, RequestInfo *pRI) {
1007 int32_t t;
1008 status_t status;
1009 RIL_SIM_APDU apdu;
1010
Robert Greenwaltbc29c432015-04-29 16:57:39 -07001011#if VDBG
Mark Salyzyn961fd022015-04-09 07:18:35 -07001012 RLOGD("dispatchSIM_APDU");
Robert Greenwaltbc29c432015-04-29 16:57:39 -07001013#endif
Howard Sue32dbfd2015-01-07 15:55:57 +08001014 memset (&apdu, 0, sizeof(RIL_SIM_APDU));
1015
1016 // Note we only check status at the end. Any single failure leads to
1017 // subsequent reads filing.
1018 status = p.readInt32(&t);
1019 apdu.sessionid = (int)t;
1020
1021 status = p.readInt32(&t);
1022 apdu.cla = (int)t;
1023
1024 status = p.readInt32(&t);
1025 apdu.instruction = (int)t;
1026
1027 status = p.readInt32(&t);
1028 apdu.p1 = (int)t;
1029
1030 status = p.readInt32(&t);
1031 apdu.p2 = (int)t;
1032
1033 status = p.readInt32(&t);
1034 apdu.p3 = (int)t;
1035
1036 apdu.data = strdupReadString(p);
1037
1038 startRequest;
1039 appendPrintBuf("%ssessionid=%d,cla=%d,ins=%d,p1=%d,p2=%d,p3=%d,data=%s",
1040 printBuf, apdu.sessionid, apdu.cla, apdu.instruction, apdu.p1, apdu.p2,
1041 apdu.p3, (char*)apdu.data);
1042 closeRequest;
1043 printRequest(pRI->token, pRI->pCI->requestNumber);
1044
1045 if (status != NO_ERROR) {
1046 goto invalid;
1047 }
1048
1049 CALL_ONREQUEST(pRI->pCI->requestNumber, &apdu, sizeof(RIL_SIM_APDU), pRI, pRI->socket_id);
1050
1051#ifdef MEMSET_FREED
1052 memsetString(apdu.data);
1053#endif
1054 free(apdu.data);
1055
1056#ifdef MEMSET_FREED
1057 memset(&apdu, 0, sizeof(RIL_SIM_APDU));
1058#endif
1059
1060 return;
1061invalid:
1062 invalidCommandBlock(pRI);
1063 return;
1064}
1065
Howard Subd82ef12015-04-12 10:25:05 +02001066
Howard Sue32dbfd2015-01-07 15:55:57 +08001067/**
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001068 * Callee expects const RIL_CallForwardInfo *
1069 * Payload is:
1070 * int32_t status/action
1071 * int32_t reason
1072 * int32_t serviceCode
1073 * int32_t toa
1074 * String number (0 length -> null)
1075 * int32_t timeSeconds
1076 */
1077static void
1078dispatchCallForward(Parcel &p, RequestInfo *pRI) {
1079 RIL_CallForwardInfo cff;
1080 int32_t t;
1081 status_t status;
1082
Mark Salyzyn961fd022015-04-09 07:18:35 -07001083 RLOGD("dispatchCallForward");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001084 memset (&cff, 0, sizeof(cff));
1085
1086 // note we only check status at the end
1087
1088 status = p.readInt32(&t);
1089 cff.status = (int)t;
1090
1091 status = p.readInt32(&t);
1092 cff.reason = (int)t;
1093
1094 status = p.readInt32(&t);
1095 cff.serviceClass = (int)t;
1096
1097 status = p.readInt32(&t);
1098 cff.toa = (int)t;
1099
1100 cff.number = strdupReadString(p);
1101
1102 status = p.readInt32(&t);
1103 cff.timeSeconds = (int)t;
1104
1105 if (status != NO_ERROR) {
1106 goto invalid;
1107 }
1108
1109 // special case: number 0-length fields is null
1110
1111 if (cff.number != NULL && strlen (cff.number) == 0) {
1112 cff.number = NULL;
1113 }
1114
1115 startRequest;
1116 appendPrintBuf("%sstat=%d,reason=%d,serv=%d,toa=%d,%s,tout=%d", printBuf,
1117 cff.status, cff.reason, cff.serviceClass, cff.toa,
1118 (char*)cff.number, cff.timeSeconds);
1119 closeRequest;
1120 printRequest(pRI->token, pRI->pCI->requestNumber);
1121
Howard Sue32dbfd2015-01-07 15:55:57 +08001122 CALL_ONREQUEST(pRI->pCI->requestNumber, &cff, sizeof(cff), pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001123
1124#ifdef MEMSET_FREED
1125 memsetString(cff.number);
1126#endif
1127
1128 free (cff.number);
1129
1130#ifdef MEMSET_FREED
1131 memset(&cff, 0, sizeof(cff));
1132#endif
1133
1134 return;
1135invalid:
1136 invalidCommandBlock(pRI);
1137 return;
1138}
1139
1140
1141static void
1142dispatchRaw(Parcel &p, RequestInfo *pRI) {
1143 int32_t len;
1144 status_t status;
1145 const void *data;
1146
1147 status = p.readInt32(&len);
1148
1149 if (status != NO_ERROR) {
1150 goto invalid;
1151 }
1152
1153 // The java code writes -1 for null arrays
1154 if (((int)len) == -1) {
1155 data = NULL;
1156 len = 0;
1157 }
1158
1159 data = p.readInplace(len);
1160
1161 startRequest;
1162 appendPrintBuf("%sraw_size=%d", printBuf, len);
1163 closeRequest;
1164 printRequest(pRI->token, pRI->pCI->requestNumber);
1165
Howard Sue32dbfd2015-01-07 15:55:57 +08001166 CALL_ONREQUEST(pRI->pCI->requestNumber, const_cast<void *>(data), len, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001167
1168 return;
1169invalid:
1170 invalidCommandBlock(pRI);
1171 return;
1172}
1173
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001174static status_t
1175constructCdmaSms(Parcel &p, RequestInfo *pRI, RIL_CDMA_SMS_Message& rcsm) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001176 int32_t t;
1177 uint8_t ut;
1178 status_t status;
1179 int32_t digitCount;
1180 int digitLimit;
1181
1182 memset(&rcsm, 0, sizeof(rcsm));
1183
1184 status = p.readInt32(&t);
1185 rcsm.uTeleserviceID = (int) t;
1186
1187 status = p.read(&ut,sizeof(ut));
1188 rcsm.bIsServicePresent = (uint8_t) ut;
1189
1190 status = p.readInt32(&t);
1191 rcsm.uServicecategory = (int) t;
1192
1193 status = p.readInt32(&t);
1194 rcsm.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
1195
1196 status = p.readInt32(&t);
1197 rcsm.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
1198
1199 status = p.readInt32(&t);
1200 rcsm.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
1201
1202 status = p.readInt32(&t);
1203 rcsm.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
1204
1205 status = p.read(&ut,sizeof(ut));
1206 rcsm.sAddress.number_of_digits= (uint8_t) ut;
1207
1208 digitLimit= MIN((rcsm.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
1209 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1210 status = p.read(&ut,sizeof(ut));
1211 rcsm.sAddress.digits[digitCount] = (uint8_t) ut;
1212 }
1213
1214 status = p.readInt32(&t);
1215 rcsm.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
1216
1217 status = p.read(&ut,sizeof(ut));
1218 rcsm.sSubAddress.odd = (uint8_t) ut;
1219
1220 status = p.read(&ut,sizeof(ut));
1221 rcsm.sSubAddress.number_of_digits = (uint8_t) ut;
1222
1223 digitLimit= MIN((rcsm.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
1224 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1225 status = p.read(&ut,sizeof(ut));
1226 rcsm.sSubAddress.digits[digitCount] = (uint8_t) ut;
1227 }
1228
1229 status = p.readInt32(&t);
1230 rcsm.uBearerDataLen = (int) t;
1231
1232 digitLimit= MIN((rcsm.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
1233 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1234 status = p.read(&ut, sizeof(ut));
1235 rcsm.aBearerData[digitCount] = (uint8_t) ut;
1236 }
1237
1238 if (status != NO_ERROR) {
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001239 return status;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001240 }
1241
1242 startRequest;
1243 appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
1244 sAddress.digit_mode=%d, sAddress.Number_mode=%d, sAddress.number_type=%d, ",
1245 printBuf, rcsm.uTeleserviceID,rcsm.bIsServicePresent,rcsm.uServicecategory,
1246 rcsm.sAddress.digit_mode, rcsm.sAddress.number_mode,rcsm.sAddress.number_type);
1247 closeRequest;
1248
1249 printRequest(pRI->token, pRI->pCI->requestNumber);
1250
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001251 return status;
1252}
1253
1254static void
1255dispatchCdmaSms(Parcel &p, RequestInfo *pRI) {
1256 RIL_CDMA_SMS_Message rcsm;
1257
Mark Salyzyn961fd022015-04-09 07:18:35 -07001258 RLOGD("dispatchCdmaSms");
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001259 if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) {
1260 goto invalid;
1261 }
1262
Howard Sue32dbfd2015-01-07 15:55:57 +08001263 CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm),pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001264
1265#ifdef MEMSET_FREED
1266 memset(&rcsm, 0, sizeof(rcsm));
1267#endif
1268
1269 return;
1270
1271invalid:
1272 invalidCommandBlock(pRI);
1273 return;
1274}
1275
1276static void
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001277dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) {
1278 RIL_IMS_SMS_Message rism;
1279 RIL_CDMA_SMS_Message rcsm;
1280
Mark Salyzyn961fd022015-04-09 07:18:35 -07001281 RLOGD("dispatchImsCdmaSms: retry=%d, messageRef=%d", retry, messageRef);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001282
1283 if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) {
1284 goto invalid;
1285 }
1286 memset(&rism, 0, sizeof(rism));
1287 rism.tech = RADIO_TECH_3GPP2;
1288 rism.retry = retry;
1289 rism.messageRef = messageRef;
1290 rism.message.cdmaMessage = &rcsm;
1291
Howard Sue32dbfd2015-01-07 15:55:57 +08001292 CALL_ONREQUEST(pRI->pCI->requestNumber, &rism,
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001293 sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t)
Howard Sue32dbfd2015-01-07 15:55:57 +08001294 +sizeof(rcsm),pRI, pRI->socket_id);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001295
1296#ifdef MEMSET_FREED
1297 memset(&rcsm, 0, sizeof(rcsm));
1298 memset(&rism, 0, sizeof(rism));
1299#endif
1300
1301 return;
1302
1303invalid:
1304 invalidCommandBlock(pRI);
1305 return;
1306}
1307
1308static void
1309dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) {
1310 RIL_IMS_SMS_Message rism;
1311 int32_t countStrings;
1312 status_t status;
1313 size_t datalen;
1314 char **pStrings;
Mark Salyzyn961fd022015-04-09 07:18:35 -07001315 RLOGD("dispatchImsGsmSms: retry=%d, messageRef=%d", retry, messageRef);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001316
1317 status = p.readInt32 (&countStrings);
1318
1319 if (status != NO_ERROR) {
1320 goto invalid;
1321 }
1322
1323 memset(&rism, 0, sizeof(rism));
1324 rism.tech = RADIO_TECH_3GPP;
1325 rism.retry = retry;
1326 rism.messageRef = messageRef;
1327
1328 startRequest;
Howard Sue32dbfd2015-01-07 15:55:57 +08001329 appendPrintBuf("%stech=%d, retry=%d, messageRef=%d, ", printBuf,
1330 (int)rism.tech, (int)rism.retry, rism.messageRef);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001331 if (countStrings == 0) {
1332 // just some non-null pointer
1333 pStrings = (char **)alloca(sizeof(char *));
1334 datalen = 0;
1335 } else if (((int)countStrings) == -1) {
1336 pStrings = NULL;
1337 datalen = 0;
1338 } else {
1339 datalen = sizeof(char *) * countStrings;
1340
1341 pStrings = (char **)alloca(datalen);
1342
1343 for (int i = 0 ; i < countStrings ; i++) {
1344 pStrings[i] = strdupReadString(p);
1345 appendPrintBuf("%s%s,", printBuf, pStrings[i]);
1346 }
1347 }
1348 removeLastChar;
1349 closeRequest;
1350 printRequest(pRI->token, pRI->pCI->requestNumber);
1351
1352 rism.message.gsmMessage = pStrings;
Howard Sue32dbfd2015-01-07 15:55:57 +08001353 CALL_ONREQUEST(pRI->pCI->requestNumber, &rism,
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001354 sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t)
Howard Sue32dbfd2015-01-07 15:55:57 +08001355 +datalen, pRI, pRI->socket_id);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001356
1357 if (pStrings != NULL) {
1358 for (int i = 0 ; i < countStrings ; i++) {
1359#ifdef MEMSET_FREED
1360 memsetString (pStrings[i]);
1361#endif
1362 free(pStrings[i]);
1363 }
1364
1365#ifdef MEMSET_FREED
1366 memset(pStrings, 0, datalen);
1367#endif
1368 }
1369
1370#ifdef MEMSET_FREED
1371 memset(&rism, 0, sizeof(rism));
1372#endif
1373 return;
1374invalid:
1375 ALOGE("dispatchImsGsmSms invalid block");
1376 invalidCommandBlock(pRI);
1377 return;
1378}
1379
1380static void
1381dispatchImsSms(Parcel &p, RequestInfo *pRI) {
1382 int32_t t;
1383 status_t status = p.readInt32(&t);
1384 RIL_RadioTechnologyFamily format;
1385 uint8_t retry;
1386 int32_t messageRef;
1387
Mark Salyzyn961fd022015-04-09 07:18:35 -07001388 RLOGD("dispatchImsSms");
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001389 if (status != NO_ERROR) {
1390 goto invalid;
1391 }
1392 format = (RIL_RadioTechnologyFamily) t;
1393
1394 // read retry field
1395 status = p.read(&retry,sizeof(retry));
1396 if (status != NO_ERROR) {
1397 goto invalid;
1398 }
1399 // read messageRef field
1400 status = p.read(&messageRef,sizeof(messageRef));
1401 if (status != NO_ERROR) {
1402 goto invalid;
1403 }
1404
1405 if (RADIO_TECH_3GPP == format) {
1406 dispatchImsGsmSms(p, pRI, retry, messageRef);
1407 } else if (RADIO_TECH_3GPP2 == format) {
1408 dispatchImsCdmaSms(p, pRI, retry, messageRef);
1409 } else {
1410 ALOGE("requestImsSendSMS invalid format value =%d", format);
1411 }
1412
1413 return;
1414
1415invalid:
1416 invalidCommandBlock(pRI);
1417 return;
1418}
1419
1420static void
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001421dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI) {
1422 RIL_CDMA_SMS_Ack rcsa;
1423 int32_t t;
1424 status_t status;
1425 int32_t digitCount;
1426
Mark Salyzyn961fd022015-04-09 07:18:35 -07001427 RLOGD("dispatchCdmaSmsAck");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001428 memset(&rcsa, 0, sizeof(rcsa));
1429
1430 status = p.readInt32(&t);
1431 rcsa.uErrorClass = (RIL_CDMA_SMS_ErrorClass) t;
1432
1433 status = p.readInt32(&t);
1434 rcsa.uSMSCauseCode = (int) t;
1435
1436 if (status != NO_ERROR) {
1437 goto invalid;
1438 }
1439
1440 startRequest;
1441 appendPrintBuf("%suErrorClass=%d, uTLStatus=%d, ",
1442 printBuf, rcsa.uErrorClass, rcsa.uSMSCauseCode);
1443 closeRequest;
1444
1445 printRequest(pRI->token, pRI->pCI->requestNumber);
1446
Howard Sue32dbfd2015-01-07 15:55:57 +08001447 CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa),pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001448
1449#ifdef MEMSET_FREED
1450 memset(&rcsa, 0, sizeof(rcsa));
1451#endif
1452
1453 return;
1454
1455invalid:
1456 invalidCommandBlock(pRI);
1457 return;
1458}
1459
1460static void
1461dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI) {
1462 int32_t t;
1463 status_t status;
1464 int32_t num;
1465
1466 status = p.readInt32(&num);
1467 if (status != NO_ERROR) {
1468 goto invalid;
1469 }
1470
Ethan Chend6e30652013-08-04 22:49:56 -07001471 {
1472 RIL_GSM_BroadcastSmsConfigInfo gsmBci[num];
1473 RIL_GSM_BroadcastSmsConfigInfo *gsmBciPtrs[num];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001474
Ethan Chend6e30652013-08-04 22:49:56 -07001475 startRequest;
1476 for (int i = 0 ; i < num ; i++ ) {
1477 gsmBciPtrs[i] = &gsmBci[i];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001478
Ethan Chend6e30652013-08-04 22:49:56 -07001479 status = p.readInt32(&t);
1480 gsmBci[i].fromServiceId = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001481
Ethan Chend6e30652013-08-04 22:49:56 -07001482 status = p.readInt32(&t);
1483 gsmBci[i].toServiceId = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001484
Ethan Chend6e30652013-08-04 22:49:56 -07001485 status = p.readInt32(&t);
1486 gsmBci[i].fromCodeScheme = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001487
Ethan Chend6e30652013-08-04 22:49:56 -07001488 status = p.readInt32(&t);
1489 gsmBci[i].toCodeScheme = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001490
Ethan Chend6e30652013-08-04 22:49:56 -07001491 status = p.readInt32(&t);
1492 gsmBci[i].selected = (uint8_t) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001493
Ethan Chend6e30652013-08-04 22:49:56 -07001494 appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId =%d, \
1495 fromCodeScheme=%d, toCodeScheme=%d, selected =%d]", printBuf, i,
1496 gsmBci[i].fromServiceId, gsmBci[i].toServiceId,
1497 gsmBci[i].fromCodeScheme, gsmBci[i].toCodeScheme,
1498 gsmBci[i].selected);
1499 }
1500 closeRequest;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001501
Ethan Chend6e30652013-08-04 22:49:56 -07001502 if (status != NO_ERROR) {
1503 goto invalid;
1504 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001505
Howard Sue32dbfd2015-01-07 15:55:57 +08001506 CALL_ONREQUEST(pRI->pCI->requestNumber,
Ethan Chend6e30652013-08-04 22:49:56 -07001507 gsmBciPtrs,
1508 num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *),
Howard Sue32dbfd2015-01-07 15:55:57 +08001509 pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001510
1511#ifdef MEMSET_FREED
Ethan Chend6e30652013-08-04 22:49:56 -07001512 memset(gsmBci, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo));
1513 memset(gsmBciPtrs, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001514#endif
Ethan Chend6e30652013-08-04 22:49:56 -07001515 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001516
1517 return;
1518
1519invalid:
1520 invalidCommandBlock(pRI);
1521 return;
1522}
1523
1524static void
1525dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI) {
1526 int32_t t;
1527 status_t status;
1528 int32_t num;
1529
1530 status = p.readInt32(&num);
1531 if (status != NO_ERROR) {
1532 goto invalid;
1533 }
1534
Ethan Chend6e30652013-08-04 22:49:56 -07001535 {
1536 RIL_CDMA_BroadcastSmsConfigInfo cdmaBci[num];
1537 RIL_CDMA_BroadcastSmsConfigInfo *cdmaBciPtrs[num];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001538
Ethan Chend6e30652013-08-04 22:49:56 -07001539 startRequest;
1540 for (int i = 0 ; i < num ; i++ ) {
1541 cdmaBciPtrs[i] = &cdmaBci[i];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001542
Ethan Chend6e30652013-08-04 22:49:56 -07001543 status = p.readInt32(&t);
1544 cdmaBci[i].service_category = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001545
Ethan Chend6e30652013-08-04 22:49:56 -07001546 status = p.readInt32(&t);
1547 cdmaBci[i].language = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001548
Ethan Chend6e30652013-08-04 22:49:56 -07001549 status = p.readInt32(&t);
1550 cdmaBci[i].selected = (uint8_t) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001551
Ethan Chend6e30652013-08-04 22:49:56 -07001552 appendPrintBuf("%s [%d: service_category=%d, language =%d, \
1553 entries.bSelected =%d]", printBuf, i, cdmaBci[i].service_category,
1554 cdmaBci[i].language, cdmaBci[i].selected);
1555 }
1556 closeRequest;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001557
Ethan Chend6e30652013-08-04 22:49:56 -07001558 if (status != NO_ERROR) {
1559 goto invalid;
1560 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001561
Howard Sue32dbfd2015-01-07 15:55:57 +08001562 CALL_ONREQUEST(pRI->pCI->requestNumber,
Ethan Chend6e30652013-08-04 22:49:56 -07001563 cdmaBciPtrs,
1564 num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *),
Howard Sue32dbfd2015-01-07 15:55:57 +08001565 pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001566
1567#ifdef MEMSET_FREED
Ethan Chend6e30652013-08-04 22:49:56 -07001568 memset(cdmaBci, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo));
1569 memset(cdmaBciPtrs, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001570#endif
Ethan Chend6e30652013-08-04 22:49:56 -07001571 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001572
1573 return;
1574
1575invalid:
1576 invalidCommandBlock(pRI);
1577 return;
1578}
1579
1580static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI) {
1581 RIL_CDMA_SMS_WriteArgs rcsw;
1582 int32_t t;
1583 uint32_t ut;
1584 uint8_t uct;
1585 status_t status;
1586 int32_t digitCount;
1587
1588 memset(&rcsw, 0, sizeof(rcsw));
1589
1590 status = p.readInt32(&t);
1591 rcsw.status = t;
1592
1593 status = p.readInt32(&t);
1594 rcsw.message.uTeleserviceID = (int) t;
1595
1596 status = p.read(&uct,sizeof(uct));
1597 rcsw.message.bIsServicePresent = (uint8_t) uct;
1598
1599 status = p.readInt32(&t);
1600 rcsw.message.uServicecategory = (int) t;
1601
1602 status = p.readInt32(&t);
1603 rcsw.message.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
1604
1605 status = p.readInt32(&t);
1606 rcsw.message.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
1607
1608 status = p.readInt32(&t);
1609 rcsw.message.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
1610
1611 status = p.readInt32(&t);
1612 rcsw.message.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
1613
1614 status = p.read(&uct,sizeof(uct));
1615 rcsw.message.sAddress.number_of_digits = (uint8_t) uct;
1616
1617 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_ADDRESS_MAX; digitCount ++) {
1618 status = p.read(&uct,sizeof(uct));
1619 rcsw.message.sAddress.digits[digitCount] = (uint8_t) uct;
1620 }
1621
1622 status = p.readInt32(&t);
1623 rcsw.message.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
1624
1625 status = p.read(&uct,sizeof(uct));
1626 rcsw.message.sSubAddress.odd = (uint8_t) uct;
1627
1628 status = p.read(&uct,sizeof(uct));
1629 rcsw.message.sSubAddress.number_of_digits = (uint8_t) uct;
1630
1631 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_SUBADDRESS_MAX; digitCount ++) {
1632 status = p.read(&uct,sizeof(uct));
1633 rcsw.message.sSubAddress.digits[digitCount] = (uint8_t) uct;
1634 }
1635
1636 status = p.readInt32(&t);
1637 rcsw.message.uBearerDataLen = (int) t;
1638
1639 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_BEARER_DATA_MAX; digitCount ++) {
1640 status = p.read(&uct, sizeof(uct));
1641 rcsw.message.aBearerData[digitCount] = (uint8_t) uct;
1642 }
1643
1644 if (status != NO_ERROR) {
1645 goto invalid;
1646 }
1647
1648 startRequest;
1649 appendPrintBuf("%sstatus=%d, message.uTeleserviceID=%d, message.bIsServicePresent=%d, \
1650 message.uServicecategory=%d, message.sAddress.digit_mode=%d, \
1651 message.sAddress.number_mode=%d, \
1652 message.sAddress.number_type=%d, ",
1653 printBuf, rcsw.status, rcsw.message.uTeleserviceID, rcsw.message.bIsServicePresent,
1654 rcsw.message.uServicecategory, rcsw.message.sAddress.digit_mode,
1655 rcsw.message.sAddress.number_mode,
1656 rcsw.message.sAddress.number_type);
1657 closeRequest;
1658
1659 printRequest(pRI->token, pRI->pCI->requestNumber);
1660
Howard Sue32dbfd2015-01-07 15:55:57 +08001661 CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw),pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001662
1663#ifdef MEMSET_FREED
1664 memset(&rcsw, 0, sizeof(rcsw));
1665#endif
1666
1667 return;
1668
1669invalid:
1670 invalidCommandBlock(pRI);
1671 return;
1672
1673}
1674
Ethan Chend6e30652013-08-04 22:49:56 -07001675// For backwards compatibility in RIL_REQUEST_SETUP_DATA_CALL.
1676// Version 4 of the RIL interface adds a new PDP type parameter to support
1677// IPv6 and dual-stack PDP contexts. When dealing with a previous version of
1678// RIL, remove the parameter from the request.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001679static void dispatchDataCall(Parcel& p, RequestInfo *pRI) {
Ethan Chend6e30652013-08-04 22:49:56 -07001680 // In RIL v3, REQUEST_SETUP_DATA_CALL takes 6 parameters.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001681 const int numParamsRilV3 = 6;
1682
Ethan Chend6e30652013-08-04 22:49:56 -07001683 // The first bytes of the RIL parcel contain the request number and the
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001684 // serial number - see processCommandBuffer(). Copy them over too.
1685 int pos = p.dataPosition();
1686
1687 int numParams = p.readInt32();
1688 if (s_callbacks.version < 4 && numParams > numParamsRilV3) {
1689 Parcel p2;
1690 p2.appendFrom(&p, 0, pos);
1691 p2.writeInt32(numParamsRilV3);
1692 for(int i = 0; i < numParamsRilV3; i++) {
1693 p2.writeString16(p.readString16());
1694 }
1695 p2.setDataPosition(pos);
1696 dispatchStrings(p2, pRI);
1697 } else {
1698 p.setDataPosition(pos);
1699 dispatchStrings(p, pRI);
1700 }
1701}
1702
1703// For backwards compatibility with RILs that dont support RIL_REQUEST_VOICE_RADIO_TECH.
Ethan Chend6e30652013-08-04 22:49:56 -07001704// When all RILs handle this request, this function can be removed and
1705// the request can be sent directly to the RIL using dispatchVoid.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001706static void dispatchVoiceRadioTech(Parcel& p, RequestInfo *pRI) {
Howard Sue32dbfd2015-01-07 15:55:57 +08001707 RIL_RadioState state = CALL_ONSTATEREQUEST((RIL_SOCKET_ID)pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001708
1709 if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) {
1710 RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1711 }
1712
Ethan Chend6e30652013-08-04 22:49:56 -07001713 // RILs that support RADIO_STATE_ON should support this request.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001714 if (RADIO_STATE_ON == state) {
1715 dispatchVoid(p, pRI);
1716 return;
1717 }
1718
Ethan Chend6e30652013-08-04 22:49:56 -07001719 // For Older RILs, that do not support RADIO_STATE_ON, assume that they
1720 // will not support this new request either and decode Voice Radio Technology
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001721 // from Radio State
1722 voiceRadioTech = decodeVoiceRadioTechnology(state);
1723
1724 if (voiceRadioTech < 0)
1725 RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0);
1726 else
1727 RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &voiceRadioTech, sizeof(int));
1728}
1729
Ethan Chend6e30652013-08-04 22:49:56 -07001730// For backwards compatibility in RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:.
1731// When all RILs handle this request, this function can be removed and
1732// the request can be sent directly to the RIL using dispatchVoid.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001733static void dispatchCdmaSubscriptionSource(Parcel& p, RequestInfo *pRI) {
Howard Sue32dbfd2015-01-07 15:55:57 +08001734 RIL_RadioState state = CALL_ONSTATEREQUEST((RIL_SOCKET_ID)pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001735
1736 if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) {
1737 RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1738 }
1739
1740 // RILs that support RADIO_STATE_ON should support this request.
1741 if (RADIO_STATE_ON == state) {
1742 dispatchVoid(p, pRI);
1743 return;
1744 }
1745
Ethan Chend6e30652013-08-04 22:49:56 -07001746 // For Older RILs, that do not support RADIO_STATE_ON, assume that they
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001747 // will not support this new request either and decode CDMA Subscription Source
Ethan Chend6e30652013-08-04 22:49:56 -07001748 // from Radio State
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001749 cdmaSubscriptionSource = decodeCdmaSubscriptionSource(state);
1750
1751 if (cdmaSubscriptionSource < 0)
1752 RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0);
1753 else
1754 RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &cdmaSubscriptionSource, sizeof(int));
1755}
1756
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001757static void dispatchSetInitialAttachApn(Parcel &p, RequestInfo *pRI)
1758{
1759 RIL_InitialAttachApn pf;
1760 int32_t t;
1761 status_t status;
1762
1763 memset(&pf, 0, sizeof(pf));
1764
1765 pf.apn = strdupReadString(p);
1766 pf.protocol = strdupReadString(p);
1767
1768 status = p.readInt32(&t);
1769 pf.authtype = (int) t;
1770
1771 pf.username = strdupReadString(p);
1772 pf.password = strdupReadString(p);
1773
1774 startRequest;
1775 appendPrintBuf("%sapn=%s, protocol=%s, auth_type=%d, username=%s, password=%s",
Andreas Schneidera8d09502015-06-23 18:41:38 +02001776 printBuf, pf.apn, pf.protocol, pf.authtype, pf.username, pf.password);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001777 closeRequest;
1778 printRequest(pRI->token, pRI->pCI->requestNumber);
1779
1780 if (status != NO_ERROR) {
1781 goto invalid;
1782 }
Howard Sue32dbfd2015-01-07 15:55:57 +08001783 CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, pRI->socket_id);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001784
1785#ifdef MEMSET_FREED
1786 memsetString(pf.apn);
1787 memsetString(pf.protocol);
1788 memsetString(pf.username);
1789 memsetString(pf.password);
1790#endif
1791
1792 free(pf.apn);
1793 free(pf.protocol);
1794 free(pf.username);
1795 free(pf.password);
1796
1797#ifdef MEMSET_FREED
1798 memset(&pf, 0, sizeof(pf));
1799#endif
1800
1801 return;
1802invalid:
1803 invalidCommandBlock(pRI);
1804 return;
1805}
1806
Howard Sue32dbfd2015-01-07 15:55:57 +08001807static void dispatchNVReadItem(Parcel &p, RequestInfo *pRI) {
1808 RIL_NV_ReadItem nvri;
1809 int32_t t;
1810 status_t status;
1811
1812 memset(&nvri, 0, sizeof(nvri));
1813
1814 status = p.readInt32(&t);
1815 nvri.itemID = (RIL_NV_Item) t;
1816
1817 if (status != NO_ERROR) {
1818 goto invalid;
1819 }
1820
1821 startRequest;
1822 appendPrintBuf("%snvri.itemID=%d, ", printBuf, nvri.itemID);
1823 closeRequest;
1824
1825 printRequest(pRI->token, pRI->pCI->requestNumber);
1826
1827 CALL_ONREQUEST(pRI->pCI->requestNumber, &nvri, sizeof(nvri), pRI, pRI->socket_id);
1828
1829#ifdef MEMSET_FREED
1830 memset(&nvri, 0, sizeof(nvri));
1831#endif
1832
1833 return;
1834
1835invalid:
1836 invalidCommandBlock(pRI);
1837 return;
1838}
1839
1840static void dispatchNVWriteItem(Parcel &p, RequestInfo *pRI) {
1841 RIL_NV_WriteItem nvwi;
1842 int32_t t;
1843 status_t status;
1844
1845 memset(&nvwi, 0, sizeof(nvwi));
1846
1847 status = p.readInt32(&t);
1848 nvwi.itemID = (RIL_NV_Item) t;
1849
1850 nvwi.value = strdupReadString(p);
1851
1852 if (status != NO_ERROR || nvwi.value == NULL) {
1853 goto invalid;
1854 }
1855
1856 startRequest;
1857 appendPrintBuf("%snvwi.itemID=%d, value=%s, ", printBuf, nvwi.itemID,
1858 nvwi.value);
1859 closeRequest;
1860
1861 printRequest(pRI->token, pRI->pCI->requestNumber);
1862
1863 CALL_ONREQUEST(pRI->pCI->requestNumber, &nvwi, sizeof(nvwi), pRI, pRI->socket_id);
1864
1865#ifdef MEMSET_FREED
1866 memsetString(nvwi.value);
1867#endif
1868
1869 free(nvwi.value);
1870
1871#ifdef MEMSET_FREED
1872 memset(&nvwi, 0, sizeof(nvwi));
1873#endif
1874
1875 return;
1876
1877invalid:
1878 invalidCommandBlock(pRI);
1879 return;
1880}
1881
1882
1883static void dispatchUiccSubscripton(Parcel &p, RequestInfo *pRI) {
1884 RIL_SelectUiccSub uicc_sub;
1885 status_t status;
1886 int32_t t;
1887 memset(&uicc_sub, 0, sizeof(uicc_sub));
1888
1889 status = p.readInt32(&t);
1890 if (status != NO_ERROR) {
1891 goto invalid;
1892 }
1893 uicc_sub.slot = (int) t;
1894
1895 status = p.readInt32(&t);
1896 if (status != NO_ERROR) {
1897 goto invalid;
1898 }
1899 uicc_sub.app_index = (int) t;
1900
1901 status = p.readInt32(&t);
1902 if (status != NO_ERROR) {
1903 goto invalid;
1904 }
1905 uicc_sub.sub_type = (RIL_SubscriptionType) t;
1906
1907 status = p.readInt32(&t);
1908 if (status != NO_ERROR) {
1909 goto invalid;
1910 }
1911 uicc_sub.act_status = (RIL_UiccSubActStatus) t;
1912
1913 startRequest;
1914 appendPrintBuf("slot=%d, app_index=%d, act_status = %d", uicc_sub.slot, uicc_sub.app_index,
1915 uicc_sub.act_status);
1916 RLOGD("dispatchUiccSubscription, slot=%d, app_index=%d, act_status = %d", uicc_sub.slot,
1917 uicc_sub.app_index, uicc_sub.act_status);
1918 closeRequest;
1919 printRequest(pRI->token, pRI->pCI->requestNumber);
1920
1921 CALL_ONREQUEST(pRI->pCI->requestNumber, &uicc_sub, sizeof(uicc_sub), pRI, pRI->socket_id);
1922
1923#ifdef MEMSET_FREED
1924 memset(&uicc_sub, 0, sizeof(uicc_sub));
1925#endif
1926 return;
1927
1928invalid:
1929 invalidCommandBlock(pRI);
1930 return;
1931}
1932
1933static void dispatchSimAuthentication(Parcel &p, RequestInfo *pRI)
1934{
1935 RIL_SimAuthentication pf;
1936 int32_t t;
1937 status_t status;
1938
1939 memset(&pf, 0, sizeof(pf));
1940
1941 status = p.readInt32(&t);
1942 pf.authContext = (int) t;
1943 pf.authData = strdupReadString(p);
1944 pf.aid = strdupReadString(p);
1945
1946 startRequest;
Andreas Schneidera8d09502015-06-23 18:41:38 +02001947 appendPrintBuf("authContext=%d, authData=%s, aid=%s", pf.authContext, pf.authData, pf.aid);
Howard Sue32dbfd2015-01-07 15:55:57 +08001948 closeRequest;
1949 printRequest(pRI->token, pRI->pCI->requestNumber);
1950
1951 if (status != NO_ERROR) {
1952 goto invalid;
1953 }
1954 CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, pRI->socket_id);
1955
1956#ifdef MEMSET_FREED
1957 memsetString(pf.authData);
1958 memsetString(pf.aid);
1959#endif
1960
1961 free(pf.authData);
1962 free(pf.aid);
1963
1964#ifdef MEMSET_FREED
1965 memset(&pf, 0, sizeof(pf));
1966#endif
1967
1968 return;
1969invalid:
1970 invalidCommandBlock(pRI);
1971 return;
1972}
1973
1974static void dispatchDataProfile(Parcel &p, RequestInfo *pRI) {
1975 int32_t t;
1976 status_t status;
1977 int32_t num;
1978
1979 status = p.readInt32(&num);
1980 if (status != NO_ERROR) {
1981 goto invalid;
1982 }
1983
1984 {
1985 RIL_DataProfileInfo dataProfiles[num];
1986 RIL_DataProfileInfo *dataProfilePtrs[num];
1987
1988 startRequest;
1989 for (int i = 0 ; i < num ; i++ ) {
1990 dataProfilePtrs[i] = &dataProfiles[i];
1991
1992 status = p.readInt32(&t);
1993 dataProfiles[i].profileId = (int) t;
1994
1995 dataProfiles[i].apn = strdupReadString(p);
1996 dataProfiles[i].protocol = strdupReadString(p);
1997 status = p.readInt32(&t);
1998 dataProfiles[i].authType = (int) t;
1999
2000 dataProfiles[i].user = strdupReadString(p);
2001 dataProfiles[i].password = strdupReadString(p);
2002
2003 status = p.readInt32(&t);
2004 dataProfiles[i].type = (int) t;
2005
2006 status = p.readInt32(&t);
2007 dataProfiles[i].maxConnsTime = (int) t;
2008 status = p.readInt32(&t);
2009 dataProfiles[i].maxConns = (int) t;
2010 status = p.readInt32(&t);
2011 dataProfiles[i].waitTime = (int) t;
2012
2013 status = p.readInt32(&t);
2014 dataProfiles[i].enabled = (int) t;
2015
2016 appendPrintBuf("%s [%d: profileId=%d, apn =%s, protocol =%s, authType =%d, \
2017 user =%s, password =%s, type =%d, maxConnsTime =%d, maxConns =%d, \
2018 waitTime =%d, enabled =%d]", printBuf, i, dataProfiles[i].profileId,
2019 dataProfiles[i].apn, dataProfiles[i].protocol, dataProfiles[i].authType,
2020 dataProfiles[i].user, dataProfiles[i].password, dataProfiles[i].type,
2021 dataProfiles[i].maxConnsTime, dataProfiles[i].maxConns,
2022 dataProfiles[i].waitTime, dataProfiles[i].enabled);
2023 }
2024 closeRequest;
2025 printRequest(pRI->token, pRI->pCI->requestNumber);
2026
2027 if (status != NO_ERROR) {
2028 goto invalid;
2029 }
2030 CALL_ONREQUEST(pRI->pCI->requestNumber,
2031 dataProfilePtrs,
2032 num * sizeof(RIL_DataProfileInfo *),
2033 pRI, pRI->socket_id);
2034
2035#ifdef MEMSET_FREED
2036 memset(dataProfiles, 0, num * sizeof(RIL_DataProfileInfo));
2037 memset(dataProfilePtrs, 0, num * sizeof(RIL_DataProfileInfo *));
2038#endif
2039 }
2040
2041 return;
2042
2043invalid:
2044 invalidCommandBlock(pRI);
2045 return;
2046}
2047
Howard Subd82ef12015-04-12 10:25:05 +02002048static void dispatchRadioCapability(Parcel &p, RequestInfo *pRI){
2049 RIL_RadioCapability rc;
2050 int32_t t;
2051 status_t status;
2052
2053 memset (&rc, 0, sizeof(RIL_RadioCapability));
2054
2055 status = p.readInt32(&t);
2056 rc.version = (int)t;
2057 if (status != NO_ERROR) {
2058 goto invalid;
2059 }
2060
2061 status = p.readInt32(&t);
2062 rc.session= (int)t;
2063 if (status != NO_ERROR) {
2064 goto invalid;
2065 }
2066
2067 status = p.readInt32(&t);
2068 rc.phase= (int)t;
2069 if (status != NO_ERROR) {
2070 goto invalid;
2071 }
2072
2073 status = p.readInt32(&t);
2074 rc.rat = (int)t;
2075 if (status != NO_ERROR) {
2076 goto invalid;
2077 }
2078
2079 status = readStringFromParcelInplace(p, rc.logicalModemUuid, sizeof(rc.logicalModemUuid));
2080 if (status != NO_ERROR) {
2081 goto invalid;
2082 }
2083
2084 status = p.readInt32(&t);
2085 rc.status = (int)t;
2086
2087 if (status != NO_ERROR) {
2088 goto invalid;
2089 }
2090
2091 startRequest;
2092 appendPrintBuf("%s [version:%d, session:%d, phase:%d, rat:%d, \
Andreas Schneidera8d09502015-06-23 18:41:38 +02002093 logicalModemUuid:%s, status:%d", printBuf, rc.version, rc.session,
2094 rc.phase, rc.rat, rc.logicalModemUuid, rc.status);
Howard Subd82ef12015-04-12 10:25:05 +02002095
2096 closeRequest;
2097 printRequest(pRI->token, pRI->pCI->requestNumber);
2098
2099 CALL_ONREQUEST(pRI->pCI->requestNumber,
2100 &rc,
2101 sizeof(RIL_RadioCapability),
2102 pRI, pRI->socket_id);
2103 return;
2104invalid:
2105 invalidCommandBlock(pRI);
2106 return;
2107}
2108
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002109static int
2110blockingWrite(int fd, const void *buffer, size_t len) {
2111 size_t writeOffset = 0;
2112 const uint8_t *toWrite;
2113
2114 toWrite = (const uint8_t *)buffer;
2115
2116 while (writeOffset < len) {
2117 ssize_t written;
2118 do {
2119 written = write (fd, toWrite + writeOffset,
2120 len - writeOffset);
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002121 } while (written < 0 && ((errno == EINTR) || (errno == EAGAIN)));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002122
2123 if (written >= 0) {
2124 writeOffset += written;
2125 } else { // written < 0
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002126 RLOGE ("RIL Response: unexpected error on write errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002127 close(fd);
2128 return -1;
2129 }
2130 }
Robert Greenwaltbc29c432015-04-29 16:57:39 -07002131#if VDBG
Dheeraj Shettycc231012014-07-02 21:27:57 +02002132 RLOGE("RIL Response bytes written:%d", writeOffset);
Robert Greenwaltbc29c432015-04-29 16:57:39 -07002133#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002134 return 0;
2135}
2136
2137static int
Howard Sue32dbfd2015-01-07 15:55:57 +08002138sendResponseRaw (const void *data, size_t dataSize, RIL_SOCKET_ID socket_id) {
2139 int fd = s_ril_param_socket.fdCommand;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002140 int ret;
2141 uint32_t header;
Howard Sue32dbfd2015-01-07 15:55:57 +08002142 pthread_mutex_t * writeMutexHook = &s_writeMutex;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002143
Robert Greenwaltbc29c432015-04-29 16:57:39 -07002144#if VDBG
Andreas Schneider822b70b2015-10-23 08:36:26 +02002145 RLOGD("Send Response to %s", rilSocketIdToString(socket_id));
Robert Greenwaltbc29c432015-04-29 16:57:39 -07002146#endif
Howard Sue32dbfd2015-01-07 15:55:57 +08002147
2148#if (SIM_COUNT >= 2)
2149 if (socket_id == RIL_SOCKET_2) {
2150 fd = s_ril_param_socket2.fdCommand;
2151 writeMutexHook = &s_writeMutex_socket2;
2152 }
2153#if (SIM_COUNT >= 3)
2154 else if (socket_id == RIL_SOCKET_3) {
2155 fd = s_ril_param_socket3.fdCommand;
2156 writeMutexHook = &s_writeMutex_socket3;
2157 }
2158#endif
2159#if (SIM_COUNT >= 4)
2160 else if (socket_id == RIL_SOCKET_4) {
2161 fd = s_ril_param_socket4.fdCommand;
2162 writeMutexHook = &s_writeMutex_socket4;
2163 }
2164#endif
2165#endif
2166 if (fd < 0) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002167 return -1;
2168 }
2169
Howard Subd82ef12015-04-12 10:25:05 +02002170 if (dataSize > MAX_COMMAND_BYTES) {
2171 RLOGE("RIL: packet larger than %u (%u)",
2172 MAX_COMMAND_BYTES, (unsigned int )dataSize);
2173
2174 return -1;
2175 }
2176
Howard Sue32dbfd2015-01-07 15:55:57 +08002177 pthread_mutex_lock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002178
2179 header = htonl(dataSize);
2180
2181 ret = blockingWrite(fd, (void *)&header, sizeof(header));
2182
2183 if (ret < 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002184 pthread_mutex_unlock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002185 return ret;
2186 }
2187
2188 ret = blockingWrite(fd, data, dataSize);
2189
2190 if (ret < 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002191 pthread_mutex_unlock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002192 return ret;
2193 }
2194
Howard Sue32dbfd2015-01-07 15:55:57 +08002195 pthread_mutex_unlock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002196
2197 return 0;
2198}
2199
2200static int
Howard Sue32dbfd2015-01-07 15:55:57 +08002201sendResponse (Parcel &p, RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002202 printResponse;
Howard Sue32dbfd2015-01-07 15:55:57 +08002203 return sendResponseRaw(p.data(), p.dataSize(), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002204}
2205
Howard Sue32dbfd2015-01-07 15:55:57 +08002206/** response is an int* pointing to an array of ints */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002207
2208static int
2209responseInts(Parcel &p, void *response, size_t responselen) {
2210 int numInts;
2211
2212 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002213 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002214 return RIL_ERRNO_INVALID_RESPONSE;
2215 }
2216 if (responselen % sizeof(int) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002217 RLOGE("responseInts: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002218 (int)responselen, (int)sizeof(int));
2219 return RIL_ERRNO_INVALID_RESPONSE;
2220 }
2221
2222 int *p_int = (int *) response;
2223
Howard Sue32dbfd2015-01-07 15:55:57 +08002224 numInts = responselen / sizeof(int);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002225 p.writeInt32 (numInts);
2226
2227 /* each int*/
2228 startResponse;
2229 for (int i = 0 ; i < numInts ; i++) {
2230 appendPrintBuf("%s%d,", printBuf, p_int[i]);
2231 p.writeInt32(p_int[i]);
2232 }
2233 removeLastChar;
2234 closeResponse;
2235
2236 return 0;
2237}
2238
Daniel Hillenbrandd0b84162015-04-12 11:53:23 +02002239static int
2240responseIntsGetPreferredNetworkType(Parcel &p, void *response, size_t responselen) {
2241 int numInts;
2242
2243 if (response == NULL && responselen != 0) {
2244 RLOGE("invalid response: NULL");
2245 return RIL_ERRNO_INVALID_RESPONSE;
2246 }
2247 if (responselen % sizeof(int) != 0) {
2248 RLOGE("responseInts: invalid response length %d expected multiple of %d\n",
2249 (int)responselen, (int)sizeof(int));
2250 return RIL_ERRNO_INVALID_RESPONSE;
2251 }
2252
2253 int *p_int = (int *) response;
2254
2255 numInts = responselen / sizeof(int);
2256 p.writeInt32 (numInts);
2257
2258 /* each int*/
2259 startResponse;
2260 for (int i = 0 ; i < numInts ; i++) {
2261 if (i == 0 && p_int[0] == 7) {
2262 RLOGD("REQUEST_GET_PREFERRED_NETWORK_TYPE: NETWORK_MODE_GLOBAL => NETWORK_MODE_WCDMA_PREF");
2263 p_int[0] = 0;
2264 }
2265 appendPrintBuf("%s%d,", printBuf, p_int[i]);
2266 p.writeInt32(p_int[i]);
2267 }
2268 removeLastChar;
2269 closeResponse;
2270
2271 return 0;
2272}
2273
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002274/** response is a char **, pointing to an array of char *'s
2275 The parcel will begin with the version */
2276static int responseStringsWithVersion(int version, Parcel &p, void *response, size_t responselen) {
2277 p.writeInt32(version);
2278 return responseStrings(p, response, responselen);
2279}
2280
2281/** response is a char **, pointing to an array of char *'s */
2282static int responseStrings(Parcel &p, void *response, size_t responselen) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002283 int numStrings;
2284
2285 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002286 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002287 return RIL_ERRNO_INVALID_RESPONSE;
2288 }
2289 if (responselen % sizeof(char *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002290 RLOGE("responseStrings: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002291 (int)responselen, (int)sizeof(char *));
2292 return RIL_ERRNO_INVALID_RESPONSE;
2293 }
2294
2295 if (response == NULL) {
2296 p.writeInt32 (0);
2297 } else {
2298 char **p_cur = (char **) response;
2299
2300 numStrings = responselen / sizeof(char *);
Dheeraj CVR48d3f722016-10-04 11:10:55 +04002301 p.writeInt32 (numStrings);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002302
2303 /* each string*/
2304 startResponse;
2305 for (int i = 0 ; i < numStrings ; i++) {
2306 appendPrintBuf("%s%s,", printBuf, (char*)p_cur[i]);
2307 writeStringToParcel (p, p_cur[i]);
2308 }
2309 removeLastChar;
2310 closeResponse;
2311 }
2312 return 0;
2313}
2314
Howard Subd82ef12015-04-12 10:25:05 +02002315
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002316/**
2317 * NULL strings are accepted
2318 * FIXME currently ignores responselen
2319 */
2320static int responseString(Parcel &p, void *response, size_t responselen) {
2321 /* one string only */
2322 startResponse;
2323 appendPrintBuf("%s%s", printBuf, (char*)response);
2324 closeResponse;
2325
2326 writeStringToParcel(p, (const char *)response);
2327
2328 return 0;
2329}
2330
2331static int responseVoid(Parcel &p, void *response, size_t responselen) {
2332 startResponse;
2333 removeLastChar;
2334 return 0;
2335}
2336
2337static int responseCallList(Parcel &p, void *response, size_t responselen) {
2338 int num;
2339
2340 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002341 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002342 return RIL_ERRNO_INVALID_RESPONSE;
2343 }
2344
2345 if (responselen % sizeof (RIL_Call *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002346 RLOGE("responseCallList: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002347 (int)responselen, (int)sizeof (RIL_Call *));
2348 return RIL_ERRNO_INVALID_RESPONSE;
2349 }
2350
2351 startResponse;
2352 /* number of call info's */
2353 num = responselen / sizeof(RIL_Call *);
2354 p.writeInt32(num);
2355
2356 for (int i = 0 ; i < num ; i++) {
2357 RIL_Call *p_cur = ((RIL_Call **) response)[i];
2358 /* each call info */
2359 p.writeInt32(p_cur->state);
2360 p.writeInt32(p_cur->index);
2361 p.writeInt32(p_cur->toa);
2362 p.writeInt32(p_cur->isMpty);
2363 p.writeInt32(p_cur->isMT);
2364 p.writeInt32(p_cur->als);
2365 p.writeInt32(p_cur->isVoice);
Andreas Schneider29472682015-01-01 19:00:04 +01002366
Christopher N. Hesse621e63e2016-02-22 21:57:39 +01002367#ifdef NEEDS_VIDEO_CALL_FIELD
Andreas Schneider29472682015-01-01 19:00:04 +01002368 p.writeInt32(p_cur->isVideo);
Sayd1052772015-12-13 17:25:01 +09002369#endif
Andreas Schneider29472682015-01-01 19:00:04 +01002370
Christopher N. Hesse621e63e2016-02-22 21:57:39 +01002371#ifdef SAMSUNG_NEXT_GEN_MODEM
Andreas Schneider29472682015-01-01 19:00:04 +01002372 /* Pass CallDetails */
2373 p.writeInt32(0);
2374 p.writeInt32(0);
2375 writeStringToParcel(p, "");
2376#endif
2377
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002378 p.writeInt32(p_cur->isVoicePrivacy);
2379 writeStringToParcel(p, p_cur->number);
2380 p.writeInt32(p_cur->numberPresentation);
2381 writeStringToParcel(p, p_cur->name);
2382 p.writeInt32(p_cur->namePresentation);
2383 // Remove when partners upgrade to version 3
2384 if ((s_callbacks.version < 3) || (p_cur->uusInfo == NULL || p_cur->uusInfo->uusData == NULL)) {
2385 p.writeInt32(0); /* UUS Information is absent */
2386 } else {
2387 RIL_UUS_Info *uusInfo = p_cur->uusInfo;
2388 p.writeInt32(1); /* UUS Information is present */
2389 p.writeInt32(uusInfo->uusType);
2390 p.writeInt32(uusInfo->uusDcs);
2391 p.writeInt32(uusInfo->uusLength);
2392 p.write(uusInfo->uusData, uusInfo->uusLength);
2393 }
2394 appendPrintBuf("%s[id=%d,%s,toa=%d,",
2395 printBuf,
2396 p_cur->index,
2397 callStateToString(p_cur->state),
2398 p_cur->toa);
2399 appendPrintBuf("%s%s,%s,als=%d,%s,%s,",
2400 printBuf,
2401 (p_cur->isMpty)?"conf":"norm",
2402 (p_cur->isMT)?"mt":"mo",
2403 p_cur->als,
2404 (p_cur->isVoice)?"voc":"nonvoc",
2405 (p_cur->isVoicePrivacy)?"evp":"noevp");
Christopher N. Hesse621e63e2016-02-22 21:57:39 +01002406#ifdef SAMSUNG_NEXT_GEN_MODEM
Andreas Schneider29472682015-01-01 19:00:04 +01002407 appendPrintBuf("%s,%s,",
2408 printBuf,
2409 (p_cur->isVideo) ? "vid" : "novid");
2410#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002411 appendPrintBuf("%s%s,cli=%d,name='%s',%d]",
2412 printBuf,
2413 p_cur->number,
2414 p_cur->numberPresentation,
2415 p_cur->name,
2416 p_cur->namePresentation);
2417 }
2418 removeLastChar;
2419 closeResponse;
2420
2421 return 0;
2422}
2423
2424static int responseSMS(Parcel &p, void *response, size_t responselen) {
2425 if (response == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002426 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002427 return RIL_ERRNO_INVALID_RESPONSE;
2428 }
2429
2430 if (responselen != sizeof (RIL_SMS_Response) ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002431 RLOGE("invalid response length %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002432 (int)responselen, (int)sizeof (RIL_SMS_Response));
2433 return RIL_ERRNO_INVALID_RESPONSE;
2434 }
2435
2436 RIL_SMS_Response *p_cur = (RIL_SMS_Response *) response;
2437
2438 p.writeInt32(p_cur->messageRef);
2439 writeStringToParcel(p, p_cur->ackPDU);
2440 p.writeInt32(p_cur->errorCode);
2441
2442 startResponse;
2443 appendPrintBuf("%s%d,%s,%d", printBuf, p_cur->messageRef,
2444 (char*)p_cur->ackPDU, p_cur->errorCode);
2445 closeResponse;
2446
2447 return 0;
2448}
2449
2450static int responseDataCallListV4(Parcel &p, void *response, size_t responselen)
2451{
2452 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002453 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002454 return RIL_ERRNO_INVALID_RESPONSE;
2455 }
2456
2457 if (responselen % sizeof(RIL_Data_Call_Response_v4) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002458 RLOGE("responseDataCallListV4: invalid response length %d expected multiple of %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002459 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v4));
2460 return RIL_ERRNO_INVALID_RESPONSE;
2461 }
2462
Howard Sue32dbfd2015-01-07 15:55:57 +08002463 // Write version
2464 p.writeInt32(4);
2465
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002466 int num = responselen / sizeof(RIL_Data_Call_Response_v4);
2467 p.writeInt32(num);
2468
2469 RIL_Data_Call_Response_v4 *p_cur = (RIL_Data_Call_Response_v4 *) response;
2470 startResponse;
2471 int i;
2472 for (i = 0; i < num; i++) {
2473 p.writeInt32(p_cur[i].cid);
2474 p.writeInt32(p_cur[i].active);
2475 writeStringToParcel(p, p_cur[i].type);
2476 // apn is not used, so don't send.
2477 writeStringToParcel(p, p_cur[i].address);
2478 appendPrintBuf("%s[cid=%d,%s,%s,%s],", printBuf,
2479 p_cur[i].cid,
2480 (p_cur[i].active==0)?"down":"up",
2481 (char*)p_cur[i].type,
2482 (char*)p_cur[i].address);
2483 }
2484 removeLastChar;
2485 closeResponse;
2486
2487 return 0;
2488}
2489
Howard Sue32dbfd2015-01-07 15:55:57 +08002490static int responseDataCallListV6(Parcel &p, void *response, size_t responselen)
2491{
2492 if (response == NULL && responselen != 0) {
2493 RLOGE("invalid response: NULL");
2494 return RIL_ERRNO_INVALID_RESPONSE;
2495 }
2496
2497 if (responselen % sizeof(RIL_Data_Call_Response_v6) != 0) {
2498 RLOGE("responseDataCallListV6: invalid response length %d expected multiple of %d",
2499 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v6));
2500 return RIL_ERRNO_INVALID_RESPONSE;
2501 }
2502
2503 // Write version
2504 p.writeInt32(6);
2505
2506 int num = responselen / sizeof(RIL_Data_Call_Response_v6);
2507 p.writeInt32(num);
2508
2509 RIL_Data_Call_Response_v6 *p_cur = (RIL_Data_Call_Response_v6 *) response;
2510 startResponse;
2511 int i;
2512 for (i = 0; i < num; i++) {
2513 p.writeInt32((int)p_cur[i].status);
2514 p.writeInt32(p_cur[i].suggestedRetryTime);
2515 p.writeInt32(p_cur[i].cid);
2516 p.writeInt32(p_cur[i].active);
2517 writeStringToParcel(p, p_cur[i].type);
2518 writeStringToParcel(p, p_cur[i].ifname);
2519 writeStringToParcel(p, p_cur[i].addresses);
2520 writeStringToParcel(p, p_cur[i].dnses);
2521 writeStringToParcel(p, p_cur[i].addresses);
2522 appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s],", printBuf,
2523 p_cur[i].status,
2524 p_cur[i].suggestedRetryTime,
2525 p_cur[i].cid,
2526 (p_cur[i].active==0)?"down":"up",
2527 (char*)p_cur[i].type,
2528 (char*)p_cur[i].ifname,
2529 (char*)p_cur[i].addresses,
2530 (char*)p_cur[i].dnses,
2531 (char*)p_cur[i].addresses);
2532 }
2533 removeLastChar;
2534 closeResponse;
2535
2536 return 0;
2537}
2538
Howard Subd82ef12015-04-12 10:25:05 +02002539static int responseDataCallListV9(Parcel &p, void *response, size_t responselen)
2540{
2541 if (response == NULL && responselen != 0) {
2542 RLOGE("invalid response: NULL");
2543 return RIL_ERRNO_INVALID_RESPONSE;
2544 }
2545
2546 if (responselen % sizeof(RIL_Data_Call_Response_v9) != 0) {
2547 RLOGE("responseDataCallListV9: invalid response length %d expected multiple of %d",
2548 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v9));
2549 return RIL_ERRNO_INVALID_RESPONSE;
2550 }
2551
2552 // Write version
2553 p.writeInt32(10);
2554
2555 int num = responselen / sizeof(RIL_Data_Call_Response_v9);
2556 p.writeInt32(num);
2557
2558 RIL_Data_Call_Response_v9 *p_cur = (RIL_Data_Call_Response_v9 *) response;
2559 startResponse;
2560 int i;
2561 for (i = 0; i < num; i++) {
2562 p.writeInt32((int)p_cur[i].status);
2563 p.writeInt32(p_cur[i].suggestedRetryTime);
2564 p.writeInt32(p_cur[i].cid);
2565 p.writeInt32(p_cur[i].active);
2566 writeStringToParcel(p, p_cur[i].type);
2567 writeStringToParcel(p, p_cur[i].ifname);
2568 writeStringToParcel(p, p_cur[i].addresses);
2569 writeStringToParcel(p, p_cur[i].dnses);
2570 writeStringToParcel(p, p_cur[i].gateways);
2571 writeStringToParcel(p, p_cur[i].pcscf);
2572 appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s],", printBuf,
2573 p_cur[i].status,
2574 p_cur[i].suggestedRetryTime,
2575 p_cur[i].cid,
2576 (p_cur[i].active==0)?"down":"up",
2577 (char*)p_cur[i].type,
2578 (char*)p_cur[i].ifname,
2579 (char*)p_cur[i].addresses,
2580 (char*)p_cur[i].dnses,
2581 (char*)p_cur[i].gateways,
2582 (char*)p_cur[i].pcscf);
2583 }
2584 removeLastChar;
2585 closeResponse;
2586
2587 return 0;
2588}
2589
Sanket Padawe9343e872016-01-11 12:45:43 -08002590static int responseDataCallListV11(Parcel &p, void *response, size_t responselen) {
2591 if (response == NULL && responselen != 0) {
2592 RLOGE("invalid response: NULL");
2593 return RIL_ERRNO_INVALID_RESPONSE;
2594 }
2595
2596 if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) {
2597 RLOGE("invalid response length %d expected multiple of %d",
2598 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v11));
2599 return RIL_ERRNO_INVALID_RESPONSE;
2600 }
2601
2602 // Write version
2603 p.writeInt32(11);
2604
2605 int num = responselen / sizeof(RIL_Data_Call_Response_v11);
2606 p.writeInt32(num);
2607
2608 RIL_Data_Call_Response_v11 *p_cur = (RIL_Data_Call_Response_v11 *) response;
2609 startResponse;
2610 int i;
2611 for (i = 0; i < num; i++) {
2612 p.writeInt32((int)p_cur[i].status);
2613 p.writeInt32(p_cur[i].suggestedRetryTime);
2614 p.writeInt32(p_cur[i].cid);
2615 p.writeInt32(p_cur[i].active);
2616 writeStringToParcel(p, p_cur[i].type);
2617 writeStringToParcel(p, p_cur[i].ifname);
2618 writeStringToParcel(p, p_cur[i].addresses);
2619 writeStringToParcel(p, p_cur[i].dnses);
2620 writeStringToParcel(p, p_cur[i].gateways);
2621 writeStringToParcel(p, p_cur[i].pcscf);
2622 p.writeInt32(p_cur[i].mtu);
2623 appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s,mtu=%d],", printBuf,
2624 p_cur[i].status,
2625 p_cur[i].suggestedRetryTime,
2626 p_cur[i].cid,
2627 (p_cur[i].active==0)?"down":"up",
2628 (char*)p_cur[i].type,
2629 (char*)p_cur[i].ifname,
2630 (char*)p_cur[i].addresses,
2631 (char*)p_cur[i].dnses,
2632 (char*)p_cur[i].gateways,
2633 (char*)p_cur[i].pcscf,
2634 p_cur[i].mtu);
2635 }
2636 removeLastChar;
2637 closeResponse;
2638
2639 return 0;
2640}
Howard Subd82ef12015-04-12 10:25:05 +02002641
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002642static int responseDataCallList(Parcel &p, void *response, size_t responselen)
2643{
Sanket Padawe9343e872016-01-11 12:45:43 -08002644 if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
2645 if (s_callbacks.version < 5) {
2646 RLOGD("responseDataCallList: v4");
2647 return responseDataCallListV4(p, response, responselen);
2648 } else if (responselen % sizeof(RIL_Data_Call_Response_v6) == 0) {
2649 return responseDataCallListV6(p, response, responselen);
2650 } else if (responselen % sizeof(RIL_Data_Call_Response_v9) == 0) {
2651 return responseDataCallListV9(p, response, responselen);
2652 } else {
2653 return responseDataCallListV11(p, response, responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002654 }
Sanket Padawe9343e872016-01-11 12:45:43 -08002655 } else { // RIL version >= 12
Howard Subd82ef12015-04-12 10:25:05 +02002656 if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) {
Sanket Padawe9343e872016-01-11 12:45:43 -08002657 RLOGE("Data structure expected is RIL_Data_Call_Response_v11");
2658 if (!isDebuggable()) {
2659 return RIL_ERRNO_INVALID_RESPONSE;
2660 } else {
2661 assert(0);
2662 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002663 }
Sanket Padawe9343e872016-01-11 12:45:43 -08002664 return responseDataCallListV11(p, response, responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002665 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002666}
2667
2668static int responseSetupDataCall(Parcel &p, void *response, size_t responselen)
2669{
2670 if (s_callbacks.version < 5) {
2671 return responseStringsWithVersion(s_callbacks.version, p, response, responselen);
2672 } else {
2673 return responseDataCallList(p, response, responselen);
2674 }
2675}
2676
2677static int responseRaw(Parcel &p, void *response, size_t responselen) {
2678 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002679 RLOGE("invalid response: NULL with responselen != 0");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002680 return RIL_ERRNO_INVALID_RESPONSE;
2681 }
2682
2683 // The java code reads -1 size as null byte array
2684 if (response == NULL) {
2685 p.writeInt32(-1);
2686 } else {
2687 p.writeInt32(responselen);
2688 p.write(response, responselen);
2689 }
2690
2691 return 0;
2692}
2693
2694
2695static int responseSIM_IO(Parcel &p, void *response, size_t responselen) {
2696 if (response == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002697 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002698 return RIL_ERRNO_INVALID_RESPONSE;
2699 }
2700
2701 if (responselen != sizeof (RIL_SIM_IO_Response) ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002702 RLOGE("invalid response length was %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002703 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
2704 return RIL_ERRNO_INVALID_RESPONSE;
2705 }
2706
2707 RIL_SIM_IO_Response *p_cur = (RIL_SIM_IO_Response *) response;
2708 p.writeInt32(p_cur->sw1);
2709 p.writeInt32(p_cur->sw2);
2710 writeStringToParcel(p, p_cur->simResponse);
2711
2712 startResponse;
2713 appendPrintBuf("%ssw1=0x%X,sw2=0x%X,%s", printBuf, p_cur->sw1, p_cur->sw2,
2714 (char*)p_cur->simResponse);
2715 closeResponse;
2716
2717
2718 return 0;
2719}
2720
2721static int responseCallForwards(Parcel &p, void *response, size_t responselen) {
2722 int num;
2723
2724 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002725 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002726 return RIL_ERRNO_INVALID_RESPONSE;
2727 }
2728
2729 if (responselen % sizeof(RIL_CallForwardInfo *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002730 RLOGE("responseCallForwards: invalid response length %d expected multiple of %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002731 (int)responselen, (int)sizeof(RIL_CallForwardInfo *));
2732 return RIL_ERRNO_INVALID_RESPONSE;
2733 }
2734
2735 /* number of call info's */
2736 num = responselen / sizeof(RIL_CallForwardInfo *);
2737 p.writeInt32(num);
2738
2739 startResponse;
2740 for (int i = 0 ; i < num ; i++) {
2741 RIL_CallForwardInfo *p_cur = ((RIL_CallForwardInfo **) response)[i];
2742
2743 p.writeInt32(p_cur->status);
2744 p.writeInt32(p_cur->reason);
2745 p.writeInt32(p_cur->serviceClass);
2746 p.writeInt32(p_cur->toa);
2747 writeStringToParcel(p, p_cur->number);
2748 p.writeInt32(p_cur->timeSeconds);
2749 appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
2750 (p_cur->status==1)?"enable":"disable",
2751 p_cur->reason, p_cur->serviceClass, p_cur->toa,
2752 (char*)p_cur->number,
2753 p_cur->timeSeconds);
2754 }
2755 removeLastChar;
2756 closeResponse;
2757
2758 return 0;
2759}
2760
2761static int responseSsn(Parcel &p, void *response, size_t responselen) {
2762 if (response == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002763 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002764 return RIL_ERRNO_INVALID_RESPONSE;
2765 }
2766
2767 if (responselen != sizeof(RIL_SuppSvcNotification)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002768 RLOGE("invalid response length was %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002769 (int)responselen, (int)sizeof (RIL_SuppSvcNotification));
2770 return RIL_ERRNO_INVALID_RESPONSE;
2771 }
2772
2773 RIL_SuppSvcNotification *p_cur = (RIL_SuppSvcNotification *) response;
2774 p.writeInt32(p_cur->notificationType);
2775 p.writeInt32(p_cur->code);
2776 p.writeInt32(p_cur->index);
2777 p.writeInt32(p_cur->type);
2778 writeStringToParcel(p, p_cur->number);
2779
2780 startResponse;
2781 appendPrintBuf("%s%s,code=%d,id=%d,type=%d,%s", printBuf,
2782 (p_cur->notificationType==0)?"mo":"mt",
2783 p_cur->code, p_cur->index, p_cur->type,
2784 (char*)p_cur->number);
2785 closeResponse;
2786
2787 return 0;
2788}
2789
2790static int responseCellList(Parcel &p, void *response, size_t responselen) {
2791 int num;
2792
2793 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002794 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002795 return RIL_ERRNO_INVALID_RESPONSE;
2796 }
2797
2798 if (responselen % sizeof (RIL_NeighboringCell *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002799 RLOGE("responseCellList: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002800 (int)responselen, (int)sizeof (RIL_NeighboringCell *));
2801 return RIL_ERRNO_INVALID_RESPONSE;
2802 }
2803
2804 startResponse;
2805 /* number of records */
2806 num = responselen / sizeof(RIL_NeighboringCell *);
2807 p.writeInt32(num);
2808
2809 for (int i = 0 ; i < num ; i++) {
2810 RIL_NeighboringCell *p_cur = ((RIL_NeighboringCell **) response)[i];
2811
2812 p.writeInt32(p_cur->rssi);
2813 writeStringToParcel (p, p_cur->cid);
2814
2815 appendPrintBuf("%s[cid=%s,rssi=%d],", printBuf,
2816 p_cur->cid, p_cur->rssi);
2817 }
2818 removeLastChar;
2819 closeResponse;
2820
2821 return 0;
2822}
2823
2824/**
2825 * Marshall the signalInfoRecord into the parcel if it exists.
2826 */
2827static void marshallSignalInfoRecord(Parcel &p,
2828 RIL_CDMA_SignalInfoRecord &p_signalInfoRecord) {
2829 p.writeInt32(p_signalInfoRecord.isPresent);
2830 p.writeInt32(p_signalInfoRecord.signalType);
2831 p.writeInt32(p_signalInfoRecord.alertPitch);
2832 p.writeInt32(p_signalInfoRecord.signal);
2833}
2834
2835static int responseCdmaInformationRecords(Parcel &p,
2836 void *response, size_t responselen) {
2837 int num;
2838 char* string8 = NULL;
2839 int buffer_lenght;
2840 RIL_CDMA_InformationRecord *infoRec;
2841
2842 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002843 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002844 return RIL_ERRNO_INVALID_RESPONSE;
2845 }
2846
2847 if (responselen != sizeof (RIL_CDMA_InformationRecords)) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002848 RLOGE("responseCdmaInformationRecords: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002849 (int)responselen, (int)sizeof (RIL_CDMA_InformationRecords *));
2850 return RIL_ERRNO_INVALID_RESPONSE;
2851 }
2852
2853 RIL_CDMA_InformationRecords *p_cur =
2854 (RIL_CDMA_InformationRecords *) response;
2855 num = MIN(p_cur->numberOfInfoRecs, RIL_CDMA_MAX_NUMBER_OF_INFO_RECS);
2856
2857 startResponse;
2858 p.writeInt32(num);
2859
2860 for (int i = 0 ; i < num ; i++) {
2861 infoRec = &p_cur->infoRec[i];
2862 p.writeInt32(infoRec->name);
2863 switch (infoRec->name) {
2864 case RIL_CDMA_DISPLAY_INFO_REC:
2865 case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
2866 if (infoRec->rec.display.alpha_len >
2867 CDMA_ALPHA_INFO_BUFFER_LENGTH) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002868 RLOGE("invalid display info response length %d \
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002869 expected not more than %d\n",
2870 (int)infoRec->rec.display.alpha_len,
2871 CDMA_ALPHA_INFO_BUFFER_LENGTH);
2872 return RIL_ERRNO_INVALID_RESPONSE;
2873 }
2874 string8 = (char*) malloc((infoRec->rec.display.alpha_len + 1)
2875 * sizeof(char) );
2876 for (int i = 0 ; i < infoRec->rec.display.alpha_len ; i++) {
2877 string8[i] = infoRec->rec.display.alpha_buf[i];
2878 }
2879 string8[(int)infoRec->rec.display.alpha_len] = '\0';
2880 writeStringToParcel(p, (const char*)string8);
2881 free(string8);
2882 string8 = NULL;
2883 break;
2884 case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
2885 case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
2886 case RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
2887 if (infoRec->rec.number.len > CDMA_NUMBER_INFO_BUFFER_LENGTH) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002888 RLOGE("invalid display info response length %d \
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002889 expected not more than %d\n",
2890 (int)infoRec->rec.number.len,
2891 CDMA_NUMBER_INFO_BUFFER_LENGTH);
2892 return RIL_ERRNO_INVALID_RESPONSE;
2893 }
2894 string8 = (char*) malloc((infoRec->rec.number.len + 1)
2895 * sizeof(char) );
2896 for (int i = 0 ; i < infoRec->rec.number.len; i++) {
2897 string8[i] = infoRec->rec.number.buf[i];
2898 }
2899 string8[(int)infoRec->rec.number.len] = '\0';
2900 writeStringToParcel(p, (const char*)string8);
2901 free(string8);
2902 string8 = NULL;
2903 p.writeInt32(infoRec->rec.number.number_type);
2904 p.writeInt32(infoRec->rec.number.number_plan);
2905 p.writeInt32(infoRec->rec.number.pi);
2906 p.writeInt32(infoRec->rec.number.si);
2907 break;
2908 case RIL_CDMA_SIGNAL_INFO_REC:
2909 p.writeInt32(infoRec->rec.signal.isPresent);
2910 p.writeInt32(infoRec->rec.signal.signalType);
2911 p.writeInt32(infoRec->rec.signal.alertPitch);
2912 p.writeInt32(infoRec->rec.signal.signal);
2913
2914 appendPrintBuf("%sisPresent=%X, signalType=%X, \
2915 alertPitch=%X, signal=%X, ",
2916 printBuf, (int)infoRec->rec.signal.isPresent,
2917 (int)infoRec->rec.signal.signalType,
2918 (int)infoRec->rec.signal.alertPitch,
2919 (int)infoRec->rec.signal.signal);
2920 removeLastChar;
2921 break;
2922 case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
2923 if (infoRec->rec.redir.redirectingNumber.len >
2924 CDMA_NUMBER_INFO_BUFFER_LENGTH) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002925 RLOGE("invalid display info response length %d \
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002926 expected not more than %d\n",
2927 (int)infoRec->rec.redir.redirectingNumber.len,
2928 CDMA_NUMBER_INFO_BUFFER_LENGTH);
2929 return RIL_ERRNO_INVALID_RESPONSE;
2930 }
2931 string8 = (char*) malloc((infoRec->rec.redir.redirectingNumber
2932 .len + 1) * sizeof(char) );
2933 for (int i = 0;
2934 i < infoRec->rec.redir.redirectingNumber.len;
2935 i++) {
2936 string8[i] = infoRec->rec.redir.redirectingNumber.buf[i];
2937 }
2938 string8[(int)infoRec->rec.redir.redirectingNumber.len] = '\0';
2939 writeStringToParcel(p, (const char*)string8);
2940 free(string8);
2941 string8 = NULL;
2942 p.writeInt32(infoRec->rec.redir.redirectingNumber.number_type);
2943 p.writeInt32(infoRec->rec.redir.redirectingNumber.number_plan);
2944 p.writeInt32(infoRec->rec.redir.redirectingNumber.pi);
2945 p.writeInt32(infoRec->rec.redir.redirectingNumber.si);
2946 p.writeInt32(infoRec->rec.redir.redirectingReason);
2947 break;
2948 case RIL_CDMA_LINE_CONTROL_INFO_REC:
2949 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPolarityIncluded);
2950 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlToggle);
2951 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlReverse);
2952 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPowerDenial);
2953
2954 appendPrintBuf("%slineCtrlPolarityIncluded=%d, \
2955 lineCtrlToggle=%d, lineCtrlReverse=%d, \
2956 lineCtrlPowerDenial=%d, ", printBuf,
2957 (int)infoRec->rec.lineCtrl.lineCtrlPolarityIncluded,
2958 (int)infoRec->rec.lineCtrl.lineCtrlToggle,
2959 (int)infoRec->rec.lineCtrl.lineCtrlReverse,
2960 (int)infoRec->rec.lineCtrl.lineCtrlPowerDenial);
2961 removeLastChar;
2962 break;
2963 case RIL_CDMA_T53_CLIR_INFO_REC:
2964 p.writeInt32((int)(infoRec->rec.clir.cause));
2965
2966 appendPrintBuf("%scause%d", printBuf, infoRec->rec.clir.cause);
2967 removeLastChar;
2968 break;
2969 case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
2970 p.writeInt32(infoRec->rec.audioCtrl.upLink);
2971 p.writeInt32(infoRec->rec.audioCtrl.downLink);
2972
2973 appendPrintBuf("%supLink=%d, downLink=%d, ", printBuf,
2974 infoRec->rec.audioCtrl.upLink,
2975 infoRec->rec.audioCtrl.downLink);
2976 removeLastChar;
2977 break;
2978 case RIL_CDMA_T53_RELEASE_INFO_REC:
2979 // TODO(Moto): See David Krause, he has the answer:)
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002980 RLOGE("RIL_CDMA_T53_RELEASE_INFO_REC: return INVALID_RESPONSE");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002981 return RIL_ERRNO_INVALID_RESPONSE;
2982 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002983 RLOGE("Incorrect name value");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002984 return RIL_ERRNO_INVALID_RESPONSE;
2985 }
2986 }
2987 closeResponse;
2988
2989 return 0;
2990}
2991
Sanket Padawe9343e872016-01-11 12:45:43 -08002992static void responseRilSignalStrengthV5(Parcel &p, RIL_SignalStrength_v10 *p_cur) {
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05302993 int gsmSignalStrength;
2994 int cdmaDbm;
2995 int evdoDbm;
2996
Sanket Padawe9343e872016-01-11 12:45:43 -08002997 gsmSignalStrength = p_cur->GW_SignalStrength.signalStrength & 0xFF;
Utkarsh Gupta8ede9fa2015-04-23 13:21:49 +05302998
2999#ifdef MODEM_TYPE_XMM6260
3000 if (gsmSignalStrength < 0 ||
3001 (gsmSignalStrength > 31 && p_cur->GW_SignalStrength.signalStrength != 99)) {
3002 gsmSignalStrength = p_cur->CDMA_SignalStrength.dbm;
3003 }
3004#else
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303005 if (gsmSignalStrength < 0) {
3006 gsmSignalStrength = 99;
3007 } else if (gsmSignalStrength > 31 && gsmSignalStrength != 99) {
3008 gsmSignalStrength = 31;
3009 }
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303010#endif
3011 p.writeInt32(gsmSignalStrength);
3012
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003013 p.writeInt32(p_cur->GW_SignalStrength.bitErrorRate);
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303014
Christopher N. Hesse621e63e2016-02-22 21:57:39 +01003015#if defined(MODEM_TYPE_XMM6262) || defined(SAMSUNG_NEXT_GEN_MODEM)
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303016 cdmaDbm = p_cur->CDMA_SignalStrength.dbm & 0xFF;
3017 if (cdmaDbm < 0) {
3018 cdmaDbm = 99;
3019 } else if (cdmaDbm > 31 && cdmaDbm != 99) {
3020 cdmaDbm = 31;
3021 }
3022#else
Caio Schnepperec042542015-04-14 08:03:43 -03003023 cdmaDbm = p_cur->CDMA_SignalStrength.dbm;
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303024#endif
3025 p.writeInt32(cdmaDbm);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003026 p.writeInt32(p_cur->CDMA_SignalStrength.ecio);
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303027
Christopher N. Hesse621e63e2016-02-22 21:57:39 +01003028#if defined(MODEM_TYPE_XMM6262) || defined(SAMSUNG_NEXT_GEN_MODEM)
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303029 evdoDbm = p_cur->EVDO_SignalStrength.dbm & 0xFF;
3030 if (evdoDbm < 0) {
3031 evdoDbm = 99;
3032 } else if (evdoDbm > 31 && evdoDbm != 99) {
3033 evdoDbm = 31;
3034 }
3035#else
3036 evdoDbm = p_cur->EVDO_SignalStrength.dbm;
3037#endif
3038 p.writeInt32(evdoDbm);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003039 p.writeInt32(p_cur->EVDO_SignalStrength.ecio);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003040 p.writeInt32(p_cur->EVDO_SignalStrength.signalNoiseRatio);
Sanket Padawe9343e872016-01-11 12:45:43 -08003041}
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003042
Sanket Padawe9343e872016-01-11 12:45:43 -08003043static void responseRilSignalStrengthV6Extra(Parcel &p, RIL_SignalStrength_v10 *p_cur) {
3044 /*
3045 * Fixup LTE for backwards compatibility
3046 */
3047 // signalStrength: -1 -> 99
3048 if (p_cur->LTE_SignalStrength.signalStrength == -1) {
3049 p_cur->LTE_SignalStrength.signalStrength = 99;
3050 }
3051 // rsrp: -1 -> INT_MAX all other negative value to positive.
3052 // So remap here
3053 if (p_cur->LTE_SignalStrength.rsrp == -1) {
3054 p_cur->LTE_SignalStrength.rsrp = INT_MAX;
3055 } else if (p_cur->LTE_SignalStrength.rsrp < -1) {
3056 p_cur->LTE_SignalStrength.rsrp = -p_cur->LTE_SignalStrength.rsrp;
3057 }
3058 // rsrq: -1 -> INT_MAX
3059 if (p_cur->LTE_SignalStrength.rsrq == -1) {
3060 p_cur->LTE_SignalStrength.rsrq = INT_MAX;
3061 }
3062 // Not remapping rssnr is already using INT_MAX
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003063
Sanket Padawe9343e872016-01-11 12:45:43 -08003064 // cqi: -1 -> INT_MAX
3065 if (p_cur->LTE_SignalStrength.cqi == -1) {
3066 p_cur->LTE_SignalStrength.cqi = INT_MAX;
3067 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003068
Sanket Padawe9343e872016-01-11 12:45:43 -08003069 p.writeInt32(p_cur->LTE_SignalStrength.signalStrength);
3070 p.writeInt32(p_cur->LTE_SignalStrength.rsrp);
3071 p.writeInt32(p_cur->LTE_SignalStrength.rsrq);
3072 p.writeInt32(p_cur->LTE_SignalStrength.rssnr);
3073 p.writeInt32(p_cur->LTE_SignalStrength.cqi);
3074}
3075
3076static void responseRilSignalStrengthV10(Parcel &p, RIL_SignalStrength_v10 *p_cur) {
3077 responseRilSignalStrengthV5(p, p_cur);
3078 responseRilSignalStrengthV6Extra(p, p_cur);
3079 p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp);
3080}
3081
3082
3083static int responseRilSignalStrength(Parcel &p,
3084 void *response, size_t responselen) {
3085 if (response == NULL && responselen != 0) {
3086 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003087 return RIL_ERRNO_INVALID_RESPONSE;
3088 }
3089
Sanket Padawe9343e872016-01-11 12:45:43 -08003090 if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
3091 if (responselen >= sizeof (RIL_SignalStrength_v5)) {
3092 RIL_SignalStrength_v10 *p_cur = ((RIL_SignalStrength_v10 *) response);
3093
3094 responseRilSignalStrengthV5(p, p_cur);
3095
3096 if (responselen >= sizeof (RIL_SignalStrength_v6)) {
3097 responseRilSignalStrengthV6Extra(p, p_cur);
3098 if (responselen >= sizeof (RIL_SignalStrength_v10)) {
3099 p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp);
3100 } else {
3101 p.writeInt32(INT_MAX);
3102 }
3103 } else {
3104 p.writeInt32(99);
3105 p.writeInt32(INT_MAX);
3106 p.writeInt32(INT_MAX);
3107 p.writeInt32(INT_MAX);
3108 p.writeInt32(INT_MAX);
3109 p.writeInt32(INT_MAX);
3110 }
3111 } else {
3112 RLOGE("invalid response length");
3113 return RIL_ERRNO_INVALID_RESPONSE;
3114 }
3115 } else { // RIL version >= 12
3116 if (responselen % sizeof(RIL_SignalStrength_v10) != 0) {
3117 RLOGE("Data structure expected is RIL_SignalStrength_v10");
3118 if (!isDebuggable()) {
3119 return RIL_ERRNO_INVALID_RESPONSE;
3120 } else {
3121 assert(0);
3122 }
3123 }
3124 RIL_SignalStrength_v10 *p_cur = ((RIL_SignalStrength_v10 *) response);
3125 responseRilSignalStrengthV10(p, p_cur);
3126 }
3127
3128 startResponse;
3129 appendPrintBuf("%s[signalStrength=%d,bitErrorRate=%d,\
3130 CDMA_SS.dbm=%d,CDMA_SSecio=%d,\
3131 EVDO_SS.dbm=%d,EVDO_SS.ecio=%d,\
3132 EVDO_SS.signalNoiseRatio=%d,\
3133 LTE_SS.signalStrength=%d,LTE_SS.rsrp=%d,LTE_SS.rsrq=%d,\
3134 LTE_SS.rssnr=%d,LTE_SS.cqi=%d,TDSCDMA_SS.rscp=%d]",
3135 printBuf,
3136 gsmSignalStrength,
3137 p_cur->GW_SignalStrength.bitErrorRate,
3138 cdmaDbm,
3139 p_cur->CDMA_SignalStrength.ecio,
3140 evdoDbm,
3141 p_cur->EVDO_SignalStrength.ecio,
3142 p_cur->EVDO_SignalStrength.signalNoiseRatio,
3143 p_cur->LTE_SignalStrength.signalStrength,
3144 p_cur->LTE_SignalStrength.rsrp,
3145 p_cur->LTE_SignalStrength.rsrq,
3146 p_cur->LTE_SignalStrength.rssnr,
3147 p_cur->LTE_SignalStrength.cqi,
3148 p_cur->TD_SCDMA_SignalStrength.rscp);
3149 closeResponse;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003150 return 0;
3151}
3152
3153static int responseCallRing(Parcel &p, void *response, size_t responselen) {
3154 if ((response == NULL) || (responselen == 0)) {
3155 return responseVoid(p, response, responselen);
3156 } else {
3157 return responseCdmaSignalInfoRecord(p, response, responselen);
3158 }
3159}
3160
3161static int responseCdmaSignalInfoRecord(Parcel &p, void *response, size_t responselen) {
3162 if (response == NULL || responselen == 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003163 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003164 return RIL_ERRNO_INVALID_RESPONSE;
3165 }
3166
3167 if (responselen != sizeof (RIL_CDMA_SignalInfoRecord)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003168 RLOGE("invalid response length %d expected sizeof (RIL_CDMA_SignalInfoRecord) of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003169 (int)responselen, (int)sizeof (RIL_CDMA_SignalInfoRecord));
3170 return RIL_ERRNO_INVALID_RESPONSE;
3171 }
3172
3173 startResponse;
3174
3175 RIL_CDMA_SignalInfoRecord *p_cur = ((RIL_CDMA_SignalInfoRecord *) response);
3176 marshallSignalInfoRecord(p, *p_cur);
3177
3178 appendPrintBuf("%s[isPresent=%d,signalType=%d,alertPitch=%d\
3179 signal=%d]",
3180 printBuf,
3181 p_cur->isPresent,
3182 p_cur->signalType,
3183 p_cur->alertPitch,
3184 p_cur->signal);
3185
3186 closeResponse;
3187 return 0;
3188}
3189
3190static int responseCdmaCallWaiting(Parcel &p, void *response,
3191 size_t responselen) {
3192 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003193 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003194 return RIL_ERRNO_INVALID_RESPONSE;
3195 }
3196
3197 if (responselen < sizeof(RIL_CDMA_CallWaiting_v6)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003198 RLOGW("Upgrade to ril version %d\n", RIL_VERSION);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003199 }
3200
3201 RIL_CDMA_CallWaiting_v6 *p_cur = ((RIL_CDMA_CallWaiting_v6 *) response);
3202
3203 writeStringToParcel(p, p_cur->number);
3204 p.writeInt32(p_cur->numberPresentation);
3205 writeStringToParcel(p, p_cur->name);
3206 marshallSignalInfoRecord(p, p_cur->signalInfoRecord);
3207
Sanket Padawe9343e872016-01-11 12:45:43 -08003208 if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
3209 if (responselen >= sizeof(RIL_CDMA_CallWaiting_v6)) {
3210 p.writeInt32(p_cur->number_type);
3211 p.writeInt32(p_cur->number_plan);
3212 } else {
3213 p.writeInt32(0);
3214 p.writeInt32(0);
3215 }
3216 } else { // RIL version >= 12
3217 if (responselen % sizeof(RIL_CDMA_CallWaiting_v6) != 0) {
3218 RLOGE("Data structure expected is RIL_CDMA_CallWaiting_v6");
3219 if (!isDebuggable()) {
3220 return RIL_ERRNO_INVALID_RESPONSE;
3221 } else {
3222 assert(0);
3223 }
3224 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003225 p.writeInt32(p_cur->number_type);
3226 p.writeInt32(p_cur->number_plan);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003227 }
3228
3229 startResponse;
3230 appendPrintBuf("%snumber=%s,numberPresentation=%d, name=%s,\
3231 signalInfoRecord[isPresent=%d,signalType=%d,alertPitch=%d\
3232 signal=%d,number_type=%d,number_plan=%d]",
3233 printBuf,
3234 p_cur->number,
3235 p_cur->numberPresentation,
3236 p_cur->name,
3237 p_cur->signalInfoRecord.isPresent,
3238 p_cur->signalInfoRecord.signalType,
3239 p_cur->signalInfoRecord.alertPitch,
3240 p_cur->signalInfoRecord.signal,
3241 p_cur->number_type,
3242 p_cur->number_plan);
3243 closeResponse;
3244
3245 return 0;
3246}
3247
Sanket Padawe9343e872016-01-11 12:45:43 -08003248static void responseSimRefreshV7(Parcel &p, void *response) {
3249 RIL_SimRefreshResponse_v7 *p_cur = ((RIL_SimRefreshResponse_v7 *) response);
3250 p.writeInt32(p_cur->result);
3251 p.writeInt32(p_cur->ef_id);
3252 writeStringToParcel(p, p_cur->aid);
3253
3254 appendPrintBuf("%sresult=%d, ef_id=%d, aid=%s",
3255 printBuf,
3256 p_cur->result,
3257 p_cur->ef_id,
3258 p_cur->aid);
3259
3260}
3261
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003262static int responseSimRefresh(Parcel &p, void *response, size_t responselen) {
3263 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003264 RLOGE("responseSimRefresh: invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003265 return RIL_ERRNO_INVALID_RESPONSE;
3266 }
3267
3268 startResponse;
Sanket Padawe9343e872016-01-11 12:45:43 -08003269 if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
3270 if (s_callbacks.version == 7) {
3271 responseSimRefreshV7(p, response);
3272 } else {
3273 int *p_cur = ((int *) response);
3274 p.writeInt32(p_cur[0]);
3275 p.writeInt32(p_cur[1]);
3276 writeStringToParcel(p, NULL);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003277
Sanket Padawe9343e872016-01-11 12:45:43 -08003278 appendPrintBuf("%sresult=%d, ef_id=%d",
3279 printBuf,
3280 p_cur[0],
3281 p_cur[1]);
3282 }
3283 } else { // RIL version >= 12
3284 if (responselen % sizeof(RIL_SimRefreshResponse_v7) != 0) {
3285 RLOGE("Data structure expected is RIL_SimRefreshResponse_v7");
3286 if (!isDebuggable()) {
3287 return RIL_ERRNO_INVALID_RESPONSE;
3288 } else {
3289 assert(0);
3290 }
3291 }
3292 responseSimRefreshV7(p, response);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003293
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003294 }
3295 closeResponse;
3296
3297 return 0;
3298}
3299
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003300static int responseCellInfoList(Parcel &p, void *response, size_t responselen)
3301{
3302 if (response == NULL && responselen != 0) {
3303 RLOGE("invalid response: NULL");
3304 return RIL_ERRNO_INVALID_RESPONSE;
3305 }
3306
3307 if (responselen % sizeof(RIL_CellInfo) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08003308 RLOGE("responseCellInfoList: invalid response length %d expected multiple of %d",
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003309 (int)responselen, (int)sizeof(RIL_CellInfo));
3310 return RIL_ERRNO_INVALID_RESPONSE;
3311 }
3312
3313 int num = responselen / sizeof(RIL_CellInfo);
3314 p.writeInt32(num);
3315
3316 RIL_CellInfo *p_cur = (RIL_CellInfo *) response;
3317 startResponse;
3318 int i;
3319 for (i = 0; i < num; i++) {
3320 appendPrintBuf("%s[%d: type=%d,registered=%d,timeStampType=%d,timeStamp=%lld", printBuf, i,
3321 p_cur->cellInfoType, p_cur->registered, p_cur->timeStampType, p_cur->timeStamp);
3322 p.writeInt32((int)p_cur->cellInfoType);
3323 p.writeInt32(p_cur->registered);
3324 p.writeInt32(p_cur->timeStampType);
3325 p.writeInt64(p_cur->timeStamp);
3326 switch(p_cur->cellInfoType) {
3327 case RIL_CELL_INFO_TYPE_GSM: {
3328 appendPrintBuf("%s GSM id: mcc=%d,mnc=%d,lac=%d,cid=%d,", printBuf,
3329 p_cur->CellInfo.gsm.cellIdentityGsm.mcc,
3330 p_cur->CellInfo.gsm.cellIdentityGsm.mnc,
3331 p_cur->CellInfo.gsm.cellIdentityGsm.lac,
3332 p_cur->CellInfo.gsm.cellIdentityGsm.cid);
3333 appendPrintBuf("%s gsmSS: ss=%d,ber=%d],", printBuf,
3334 p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength,
3335 p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
3336
3337 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mcc);
3338 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mnc);
3339 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.lac);
3340 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.cid);
3341 p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength);
3342 p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
3343 break;
3344 }
3345 case RIL_CELL_INFO_TYPE_WCDMA: {
3346 appendPrintBuf("%s WCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,psc=%d,", printBuf,
3347 p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc,
3348 p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc,
3349 p_cur->CellInfo.wcdma.cellIdentityWcdma.lac,
3350 p_cur->CellInfo.wcdma.cellIdentityWcdma.cid,
3351 p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
3352 appendPrintBuf("%s wcdmaSS: ss=%d,ber=%d],", printBuf,
3353 p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength,
3354 p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
3355
3356 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc);
3357 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc);
3358 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.lac);
3359 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.cid);
3360 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
3361 p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength);
3362 p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
3363 break;
3364 }
3365 case RIL_CELL_INFO_TYPE_CDMA: {
3366 appendPrintBuf("%s CDMA id: nId=%d,sId=%d,bsId=%d,long=%d,lat=%d", printBuf,
3367 p_cur->CellInfo.cdma.cellIdentityCdma.networkId,
3368 p_cur->CellInfo.cdma.cellIdentityCdma.systemId,
3369 p_cur->CellInfo.cdma.cellIdentityCdma.basestationId,
3370 p_cur->CellInfo.cdma.cellIdentityCdma.longitude,
3371 p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
3372
3373 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.networkId);
3374 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.systemId);
3375 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.basestationId);
3376 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.longitude);
3377 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
3378
3379 appendPrintBuf("%s cdmaSS: dbm=%d ecio=%d evdoSS: dbm=%d,ecio=%d,snr=%d", printBuf,
3380 p_cur->CellInfo.cdma.signalStrengthCdma.dbm,
3381 p_cur->CellInfo.cdma.signalStrengthCdma.ecio,
3382 p_cur->CellInfo.cdma.signalStrengthEvdo.dbm,
3383 p_cur->CellInfo.cdma.signalStrengthEvdo.ecio,
3384 p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
3385
3386 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.dbm);
3387 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.ecio);
3388 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.dbm);
3389 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.ecio);
3390 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
3391 break;
3392 }
3393 case RIL_CELL_INFO_TYPE_LTE: {
3394 appendPrintBuf("%s LTE id: mcc=%d,mnc=%d,ci=%d,pci=%d,tac=%d", printBuf,
3395 p_cur->CellInfo.lte.cellIdentityLte.mcc,
3396 p_cur->CellInfo.lte.cellIdentityLte.mnc,
3397 p_cur->CellInfo.lte.cellIdentityLte.ci,
3398 p_cur->CellInfo.lte.cellIdentityLte.pci,
3399 p_cur->CellInfo.lte.cellIdentityLte.tac);
3400
3401 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mcc);
3402 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mnc);
3403 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.ci);
3404 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.pci);
3405 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.tac);
3406
3407 appendPrintBuf("%s lteSS: ss=%d,rsrp=%d,rsrq=%d,rssnr=%d,cqi=%d,ta=%d", printBuf,
3408 p_cur->CellInfo.lte.signalStrengthLte.signalStrength,
3409 p_cur->CellInfo.lte.signalStrengthLte.rsrp,
3410 p_cur->CellInfo.lte.signalStrengthLte.rsrq,
3411 p_cur->CellInfo.lte.signalStrengthLte.rssnr,
3412 p_cur->CellInfo.lte.signalStrengthLte.cqi,
3413 p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
3414 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.signalStrength);
3415 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrp);
3416 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrq);
3417 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rssnr);
3418 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.cqi);
3419 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
3420 break;
3421 }
Howard Sue32dbfd2015-01-07 15:55:57 +08003422 case RIL_CELL_INFO_TYPE_TD_SCDMA: {
3423 appendPrintBuf("%s TDSCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,cpid=%d,", printBuf,
3424 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc,
3425 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc,
3426 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac,
3427 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid,
3428 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid);
3429 appendPrintBuf("%s tdscdmaSS: rscp=%d],", printBuf,
3430 p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp);
3431
3432 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc);
3433 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc);
3434 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac);
3435 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid);
3436 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid);
3437 p.writeInt32(p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp);
3438 break;
3439 }
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003440 }
3441 p_cur += 1;
3442 }
3443 removeLastChar;
3444 closeResponse;
3445
3446 return 0;
3447}
3448
Howard Sue32dbfd2015-01-07 15:55:57 +08003449static int responseHardwareConfig(Parcel &p, void *response, size_t responselen)
3450{
3451 if (response == NULL && responselen != 0) {
3452 RLOGE("invalid response: NULL");
3453 return RIL_ERRNO_INVALID_RESPONSE;
3454 }
3455
3456 if (responselen % sizeof(RIL_HardwareConfig) != 0) {
3457 RLOGE("responseHardwareConfig: invalid response length %d expected multiple of %d",
3458 (int)responselen, (int)sizeof(RIL_HardwareConfig));
3459 return RIL_ERRNO_INVALID_RESPONSE;
3460 }
3461
3462 int num = responselen / sizeof(RIL_HardwareConfig);
3463 int i;
3464 RIL_HardwareConfig *p_cur = (RIL_HardwareConfig *) response;
3465
3466 p.writeInt32(num);
3467
3468 startResponse;
3469 for (i = 0; i < num; i++) {
3470 switch (p_cur[i].type) {
3471 case RIL_HARDWARE_CONFIG_MODEM: {
3472 writeStringToParcel(p, p_cur[i].uuid);
3473 p.writeInt32((int)p_cur[i].state);
3474 p.writeInt32(p_cur[i].cfg.modem.rat);
3475 p.writeInt32(p_cur[i].cfg.modem.maxVoice);
3476 p.writeInt32(p_cur[i].cfg.modem.maxData);
3477 p.writeInt32(p_cur[i].cfg.modem.maxStandby);
3478
3479 appendPrintBuf("%s modem: uuid=%s,state=%d,rat=%08x,maxV=%d,maxD=%d,maxS=%d", printBuf,
3480 p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.modem.rat,
3481 p_cur[i].cfg.modem.maxVoice, p_cur[i].cfg.modem.maxData, p_cur[i].cfg.modem.maxStandby);
3482 break;
3483 }
3484 case RIL_HARDWARE_CONFIG_SIM: {
3485 writeStringToParcel(p, p_cur[i].uuid);
3486 p.writeInt32((int)p_cur[i].state);
3487 writeStringToParcel(p, p_cur[i].cfg.sim.modemUuid);
3488
3489 appendPrintBuf("%s sim: uuid=%s,state=%d,modem-uuid=%s", printBuf,
3490 p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.sim.modemUuid);
3491 break;
3492 }
3493 }
3494 }
3495 removeLastChar;
3496 closeResponse;
3497 return 0;
3498}
3499
Howard Subd82ef12015-04-12 10:25:05 +02003500static int responseRadioCapability(Parcel &p, void *response, size_t responselen) {
3501 if (response == NULL) {
3502 RLOGE("invalid response: NULL");
3503 return RIL_ERRNO_INVALID_RESPONSE;
3504 }
3505
3506 if (responselen != sizeof (RIL_RadioCapability) ) {
3507 RLOGE("invalid response length was %d expected %d",
3508 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
3509 return RIL_ERRNO_INVALID_RESPONSE;
3510 }
3511
3512 RIL_RadioCapability *p_cur = (RIL_RadioCapability *) response;
3513 p.writeInt32(p_cur->version);
3514 p.writeInt32(p_cur->session);
3515 p.writeInt32(p_cur->phase);
3516 p.writeInt32(p_cur->rat);
3517 writeStringToParcel(p, p_cur->logicalModemUuid);
3518 p.writeInt32(p_cur->status);
3519
3520 startResponse;
3521 appendPrintBuf("%s[version=%d,session=%d,phase=%d,\
Andreas Schneidera8d09502015-06-23 18:41:38 +02003522 rat=%d,logicalModemUuid=%s,status=%d]",
Howard Subd82ef12015-04-12 10:25:05 +02003523 printBuf,
3524 p_cur->version,
3525 p_cur->session,
3526 p_cur->phase,
3527 p_cur->rat,
3528 p_cur->logicalModemUuid,
3529 p_cur->status);
3530 closeResponse;
3531 return 0;
3532}
3533
3534static int responseSSData(Parcel &p, void *response, size_t responselen) {
3535 RLOGD("In responseSSData");
3536 int num;
3537
3538 if (response == NULL && responselen != 0) {
3539 RLOGE("invalid response length was %d expected %d",
3540 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
3541 return RIL_ERRNO_INVALID_RESPONSE;
3542 }
3543
3544 if (responselen != sizeof(RIL_StkCcUnsolSsResponse)) {
3545 RLOGE("invalid response length %d, expected %d",
3546 (int)responselen, (int)sizeof(RIL_StkCcUnsolSsResponse));
3547 return RIL_ERRNO_INVALID_RESPONSE;
3548 }
3549
3550 startResponse;
3551 RIL_StkCcUnsolSsResponse *p_cur = (RIL_StkCcUnsolSsResponse *) response;
3552 p.writeInt32(p_cur->serviceType);
3553 p.writeInt32(p_cur->requestType);
3554 p.writeInt32(p_cur->teleserviceType);
3555 p.writeInt32(p_cur->serviceClass);
3556 p.writeInt32(p_cur->result);
3557
3558 if (isServiceTypeCfQuery(p_cur->serviceType, p_cur->requestType)) {
3559 RLOGD("responseSSData CF type, num of Cf elements %d", p_cur->cfData.numValidIndexes);
3560 if (p_cur->cfData.numValidIndexes > NUM_SERVICE_CLASSES) {
3561 RLOGE("numValidIndexes is greater than max value %d, "
3562 "truncating it to max value", NUM_SERVICE_CLASSES);
3563 p_cur->cfData.numValidIndexes = NUM_SERVICE_CLASSES;
3564 }
3565 /* number of call info's */
3566 p.writeInt32(p_cur->cfData.numValidIndexes);
3567
3568 for (int i = 0; i < p_cur->cfData.numValidIndexes; i++) {
3569 RIL_CallForwardInfo cf = p_cur->cfData.cfInfo[i];
3570
3571 p.writeInt32(cf.status);
3572 p.writeInt32(cf.reason);
3573 p.writeInt32(cf.serviceClass);
3574 p.writeInt32(cf.toa);
3575 writeStringToParcel(p, cf.number);
3576 p.writeInt32(cf.timeSeconds);
3577 appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
3578 (cf.status==1)?"enable":"disable", cf.reason, cf.serviceClass, cf.toa,
3579 (char*)cf.number, cf.timeSeconds);
3580 RLOGD("Data: %d,reason=%d,cls=%d,toa=%d,num=%s,tout=%d],", cf.status,
3581 cf.reason, cf.serviceClass, cf.toa, (char*)cf.number, cf.timeSeconds);
3582 }
3583 } else {
3584 p.writeInt32 (SS_INFO_MAX);
3585
3586 /* each int*/
3587 for (int i = 0; i < SS_INFO_MAX; i++) {
3588 appendPrintBuf("%s%d,", printBuf, p_cur->ssInfo[i]);
3589 RLOGD("Data: %d",p_cur->ssInfo[i]);
3590 p.writeInt32(p_cur->ssInfo[i]);
3591 }
3592 }
3593 removeLastChar;
3594 closeResponse;
3595
3596 return 0;
3597}
3598
3599static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType) {
3600 if ((reqType == SS_INTERROGATION) &&
3601 (serType == SS_CFU ||
3602 serType == SS_CF_BUSY ||
3603 serType == SS_CF_NO_REPLY ||
3604 serType == SS_CF_NOT_REACHABLE ||
3605 serType == SS_CF_ALL ||
3606 serType == SS_CF_ALL_CONDITIONAL)) {
3607 return true;
3608 }
3609 return false;
3610}
3611
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003612static void triggerEvLoop() {
3613 int ret;
3614 if (!pthread_equal(pthread_self(), s_tid_dispatch)) {
3615 /* trigger event loop to wakeup. No reason to do this,
3616 * if we're in the event loop thread */
3617 do {
3618 ret = write (s_fdWakeupWrite, " ", 1);
3619 } while (ret < 0 && errno == EINTR);
3620 }
3621}
3622
3623static void rilEventAddWakeup(struct ril_event *ev) {
3624 ril_event_add(ev);
3625 triggerEvLoop();
3626}
3627
3628static void sendSimStatusAppInfo(Parcel &p, int num_apps, RIL_AppStatus appStatus[]) {
3629 p.writeInt32(num_apps);
3630 startResponse;
3631 for (int i = 0; i < num_apps; i++) {
3632 p.writeInt32(appStatus[i].app_type);
3633 p.writeInt32(appStatus[i].app_state);
3634 p.writeInt32(appStatus[i].perso_substate);
3635 writeStringToParcel(p, (const char*)(appStatus[i].aid_ptr));
3636 writeStringToParcel(p, (const char*)
3637 (appStatus[i].app_label_ptr));
3638 p.writeInt32(appStatus[i].pin1_replaced);
3639 p.writeInt32(appStatus[i].pin1);
3640 p.writeInt32(appStatus[i].pin2);
3641 appendPrintBuf("%s[app_type=%d,app_state=%d,perso_substate=%d,\
3642 aid_ptr=%s,app_label_ptr=%s,pin1_replaced=%d,pin1=%d,pin2=%d],",
3643 printBuf,
3644 appStatus[i].app_type,
3645 appStatus[i].app_state,
3646 appStatus[i].perso_substate,
3647 appStatus[i].aid_ptr,
3648 appStatus[i].app_label_ptr,
3649 appStatus[i].pin1_replaced,
3650 appStatus[i].pin1,
3651 appStatus[i].pin2);
3652 }
3653 closeResponse;
3654}
3655
Sanket Padawe9343e872016-01-11 12:45:43 -08003656static void responseSimStatusV5(Parcel &p, void *response) {
3657 RIL_CardStatus_v5 *p_cur = ((RIL_CardStatus_v5 *) response);
3658
3659 p.writeInt32(p_cur->card_state);
3660 p.writeInt32(p_cur->universal_pin_state);
3661 p.writeInt32(p_cur->gsm_umts_subscription_app_index);
3662 p.writeInt32(p_cur->cdma_subscription_app_index);
3663
3664 sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
3665}
3666
3667static void responseSimStatusV6(Parcel &p, void *response) {
3668 RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
3669
3670 p.writeInt32(p_cur->card_state);
3671 p.writeInt32(p_cur->universal_pin_state);
3672 p.writeInt32(p_cur->gsm_umts_subscription_app_index);
3673 p.writeInt32(p_cur->cdma_subscription_app_index);
3674 p.writeInt32(p_cur->ims_subscription_app_index);
3675
3676 sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
3677}
3678
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003679static int responseSimStatus(Parcel &p, void *response, size_t responselen) {
Howard Sue32dbfd2015-01-07 15:55:57 +08003680 int i;
3681
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003682 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003683 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003684 return RIL_ERRNO_INVALID_RESPONSE;
3685 }
3686
Sanket Padawe9343e872016-01-11 12:45:43 -08003687 if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
3688 if (responselen == sizeof (RIL_CardStatus_v6)) {
3689 responseSimStatusV6(p, response);
3690 } else if (responselen == sizeof (RIL_CardStatus_v5)) {
3691 responseSimStatusV5(p, response);
3692 } else {
3693 RLOGE("responseSimStatus: A RilCardStatus_v6 or _v5 expected\n");
3694 return RIL_ERRNO_INVALID_RESPONSE;
3695 }
3696 } else { // RIL version >= 12
3697 if (responselen % sizeof(RIL_CardStatus_v6) != 0) {
3698 RLOGE("Data structure expected is RIL_CardStatus_v6");
3699 if (!isDebuggable()) {
3700 return RIL_ERRNO_INVALID_RESPONSE;
3701 } else {
3702 assert(0);
3703 }
3704 }
3705 responseSimStatusV6(p, response);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003706 }
3707
3708 return 0;
3709}
3710
3711static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen) {
3712 int num = responselen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *);
3713 p.writeInt32(num);
3714
3715 startResponse;
3716 RIL_GSM_BroadcastSmsConfigInfo **p_cur =
3717 (RIL_GSM_BroadcastSmsConfigInfo **) response;
3718 for (int i = 0; i < num; i++) {
3719 p.writeInt32(p_cur[i]->fromServiceId);
3720 p.writeInt32(p_cur[i]->toServiceId);
3721 p.writeInt32(p_cur[i]->fromCodeScheme);
3722 p.writeInt32(p_cur[i]->toCodeScheme);
3723 p.writeInt32(p_cur[i]->selected);
3724
3725 appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId=%d, \
3726 fromCodeScheme=%d, toCodeScheme=%d, selected =%d]",
3727 printBuf, i, p_cur[i]->fromServiceId, p_cur[i]->toServiceId,
3728 p_cur[i]->fromCodeScheme, p_cur[i]->toCodeScheme,
3729 p_cur[i]->selected);
3730 }
3731 closeResponse;
3732
3733 return 0;
3734}
3735
3736static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen) {
3737 RIL_CDMA_BroadcastSmsConfigInfo **p_cur =
3738 (RIL_CDMA_BroadcastSmsConfigInfo **) response;
3739
3740 int num = responselen / sizeof (RIL_CDMA_BroadcastSmsConfigInfo *);
3741 p.writeInt32(num);
3742
3743 startResponse;
3744 for (int i = 0 ; i < num ; i++ ) {
3745 p.writeInt32(p_cur[i]->service_category);
3746 p.writeInt32(p_cur[i]->language);
3747 p.writeInt32(p_cur[i]->selected);
3748
3749 appendPrintBuf("%s [%d: srvice_category=%d, language =%d, \
3750 selected =%d], ",
3751 printBuf, i, p_cur[i]->service_category, p_cur[i]->language,
3752 p_cur[i]->selected);
3753 }
3754 closeResponse;
3755
3756 return 0;
3757}
3758
3759static int responseCdmaSms(Parcel &p, void *response, size_t responselen) {
3760 int num;
3761 int digitCount;
3762 int digitLimit;
3763 uint8_t uct;
3764 void* dest;
3765
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003766 RLOGD("Inside responseCdmaSms");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003767
3768 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003769 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003770 return RIL_ERRNO_INVALID_RESPONSE;
3771 }
3772
3773 if (responselen != sizeof(RIL_CDMA_SMS_Message)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003774 RLOGE("invalid response length was %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003775 (int)responselen, (int)sizeof(RIL_CDMA_SMS_Message));
3776 return RIL_ERRNO_INVALID_RESPONSE;
3777 }
3778
3779 RIL_CDMA_SMS_Message *p_cur = (RIL_CDMA_SMS_Message *) response;
3780 p.writeInt32(p_cur->uTeleserviceID);
3781 p.write(&(p_cur->bIsServicePresent),sizeof(uct));
3782 p.writeInt32(p_cur->uServicecategory);
3783 p.writeInt32(p_cur->sAddress.digit_mode);
3784 p.writeInt32(p_cur->sAddress.number_mode);
3785 p.writeInt32(p_cur->sAddress.number_type);
3786 p.writeInt32(p_cur->sAddress.number_plan);
3787 p.write(&(p_cur->sAddress.number_of_digits), sizeof(uct));
3788 digitLimit= MIN((p_cur->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
3789 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
3790 p.write(&(p_cur->sAddress.digits[digitCount]),sizeof(uct));
3791 }
3792
3793 p.writeInt32(p_cur->sSubAddress.subaddressType);
3794 p.write(&(p_cur->sSubAddress.odd),sizeof(uct));
3795 p.write(&(p_cur->sSubAddress.number_of_digits),sizeof(uct));
3796 digitLimit= MIN((p_cur->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
3797 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
3798 p.write(&(p_cur->sSubAddress.digits[digitCount]),sizeof(uct));
3799 }
3800
3801 digitLimit= MIN((p_cur->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
3802 p.writeInt32(p_cur->uBearerDataLen);
3803 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
3804 p.write(&(p_cur->aBearerData[digitCount]), sizeof(uct));
3805 }
3806
3807 startResponse;
3808 appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
3809 sAddress.digit_mode=%d, sAddress.number_mode=%d, sAddress.number_type=%d, ",
3810 printBuf, p_cur->uTeleserviceID,p_cur->bIsServicePresent,p_cur->uServicecategory,
3811 p_cur->sAddress.digit_mode, p_cur->sAddress.number_mode,p_cur->sAddress.number_type);
3812 closeResponse;
3813
3814 return 0;
3815}
3816
Howard Sue32dbfd2015-01-07 15:55:57 +08003817static int responseDcRtInfo(Parcel &p, void *response, size_t responselen)
3818{
3819 int num = responselen / sizeof(RIL_DcRtInfo);
3820 if ((responselen % sizeof(RIL_DcRtInfo) != 0) || (num != 1)) {
3821 RLOGE("responseDcRtInfo: invalid response length %d expected multiple of %d",
3822 (int)responselen, (int)sizeof(RIL_DcRtInfo));
3823 return RIL_ERRNO_INVALID_RESPONSE;
3824 }
3825
3826 startResponse;
3827 RIL_DcRtInfo *pDcRtInfo = (RIL_DcRtInfo *)response;
3828 p.writeInt64(pDcRtInfo->time);
3829 p.writeInt32(pDcRtInfo->powerState);
3830 appendPrintBuf("%s[time=%d,powerState=%d]", printBuf,
3831 pDcRtInfo->time,
Andreas Schneidera8d09502015-06-23 18:41:38 +02003832 (int)pDcRtInfo->powerState);
Howard Sue32dbfd2015-01-07 15:55:57 +08003833 closeResponse;
3834
3835 return 0;
3836}
3837
fenglu9bdede02015-04-14 14:53:55 -07003838static int responseLceStatus(Parcel &p, void *response, size_t responselen) {
3839 if (response == NULL || responselen != sizeof(RIL_LceStatusInfo)) {
3840 if (response == NULL) {
3841 RLOGE("invalid response: NULL");
3842 }
3843 else {
3844 RLOGE("responseLceStatus: invalid response length %d expecting len: d%",
3845 sizeof(RIL_LceStatusInfo), responselen);
3846 }
3847 return RIL_ERRNO_INVALID_RESPONSE;
3848 }
3849
3850 RIL_LceStatusInfo *p_cur = (RIL_LceStatusInfo *)response;
3851 p.write((void *)p_cur, 1); // p_cur->lce_status takes one byte.
3852 p.writeInt32(p_cur->actual_interval_ms);
3853
3854 startResponse;
3855 appendPrintBuf("LCE Status: %d, actual_interval_ms: %d",
3856 p_cur->lce_status, p_cur->actual_interval_ms);
3857 closeResponse;
3858
3859 return 0;
3860}
3861
3862static int responseLceData(Parcel &p, void *response, size_t responselen) {
3863 if (response == NULL || responselen != sizeof(RIL_LceDataInfo)) {
3864 if (response == NULL) {
3865 RLOGE("invalid response: NULL");
3866 }
3867 else {
3868 RLOGE("responseLceData: invalid response length %d expecting len: d%",
3869 sizeof(RIL_LceDataInfo), responselen);
3870 }
3871 return RIL_ERRNO_INVALID_RESPONSE;
3872 }
3873
3874 RIL_LceDataInfo *p_cur = (RIL_LceDataInfo *)response;
3875 p.writeInt32(p_cur->last_hop_capacity_kbps);
3876
3877 /* p_cur->confidence_level and p_cur->lce_suspended take 1 byte each.*/
3878 p.write((void *)&(p_cur->confidence_level), 1);
3879 p.write((void *)&(p_cur->lce_suspended), 1);
3880
3881 startResponse;
Hyejine942c332015-09-14 16:27:28 -07003882 appendPrintBuf("LCE info received: capacity %d confidence level %d \
3883 and suspended %d",
fenglu9bdede02015-04-14 14:53:55 -07003884 p_cur->last_hop_capacity_kbps, p_cur->confidence_level,
3885 p_cur->lce_suspended);
3886 closeResponse;
3887
3888 return 0;
3889}
3890
Prerepa Viswanadham8e755592015-05-28 00:37:32 -07003891static int responseActivityData(Parcel &p, void *response, size_t responselen) {
3892 if (response == NULL || responselen != sizeof(RIL_ActivityStatsInfo)) {
3893 if (response == NULL) {
3894 RLOGE("invalid response: NULL");
3895 }
3896 else {
3897 RLOGE("responseActivityData: invalid response length %d expecting len: d%",
3898 sizeof(RIL_ActivityStatsInfo), responselen);
3899 }
3900 return RIL_ERRNO_INVALID_RESPONSE;
3901 }
3902
3903 RIL_ActivityStatsInfo *p_cur = (RIL_ActivityStatsInfo *)response;
3904 p.writeInt32(p_cur->sleep_mode_time_ms);
3905 p.writeInt32(p_cur->idle_mode_time_ms);
3906 for(int i = 0; i < RIL_NUM_TX_POWER_LEVELS; i++) {
3907 p.writeInt32(p_cur->tx_mode_time_ms[i]);
3908 }
3909 p.writeInt32(p_cur->rx_mode_time_ms);
3910
3911 startResponse;
Hyejine942c332015-09-14 16:27:28 -07003912 appendPrintBuf("Modem activity info received: sleep_mode_time_ms %d idle_mode_time_ms %d \
3913 tx_mode_time_ms %d %d %d %d %d and rx_mode_time_ms %d",
Prerepa Viswanadham8e755592015-05-28 00:37:32 -07003914 p_cur->sleep_mode_time_ms, p_cur->idle_mode_time_ms, p_cur->tx_mode_time_ms[0],
3915 p_cur->tx_mode_time_ms[1], p_cur->tx_mode_time_ms[2], p_cur->tx_mode_time_ms[3],
3916 p_cur->tx_mode_time_ms[4], p_cur->rx_mode_time_ms);
3917 closeResponse;
3918
3919 return 0;
3920}
3921
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003922/**
3923 * A write on the wakeup fd is done just to pop us out of select()
3924 * We empty the buffer here and then ril_event will reset the timers on the
3925 * way back down
3926 */
3927static void processWakeupCallback(int fd, short flags, void *param) {
3928 char buff[16];
3929 int ret;
3930
Ethan Chend6e30652013-08-04 22:49:56 -07003931 RLOGV("processWakeupCallback");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003932
3933 /* empty our wakeup socket out */
3934 do {
3935 ret = read(s_fdWakeupRead, &buff, sizeof(buff));
3936 } while (ret > 0 || (ret < 0 && errno == EINTR));
3937}
3938
Howard Sue32dbfd2015-01-07 15:55:57 +08003939static void onCommandsSocketClosed(RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003940 int ret;
3941 RequestInfo *p_cur;
Howard Sue32dbfd2015-01-07 15:55:57 +08003942 /* Hook for current context
3943 pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
3944 pthread_mutex_t * pendingRequestsMutexHook = &s_pendingRequestsMutex;
3945 /* pendingRequestsHook refer to &s_pendingRequests */
3946 RequestInfo ** pendingRequestsHook = &s_pendingRequests;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003947
Howard Sue32dbfd2015-01-07 15:55:57 +08003948#if (SIM_COUNT >= 2)
3949 if (socket_id == RIL_SOCKET_2) {
3950 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
3951 pendingRequestsHook = &s_pendingRequests_socket2;
3952 }
3953#if (SIM_COUNT >= 3)
3954 else if (socket_id == RIL_SOCKET_3) {
3955 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
3956 pendingRequestsHook = &s_pendingRequests_socket3;
3957 }
3958#endif
3959#if (SIM_COUNT >= 4)
3960 else if (socket_id == RIL_SOCKET_4) {
3961 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
3962 pendingRequestsHook = &s_pendingRequests_socket4;
3963 }
3964#endif
3965#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003966 /* mark pending requests as "cancelled" so we dont report responses */
Howard Sue32dbfd2015-01-07 15:55:57 +08003967 ret = pthread_mutex_lock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003968 assert (ret == 0);
3969
Howard Sue32dbfd2015-01-07 15:55:57 +08003970 p_cur = *pendingRequestsHook;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003971
Howard Sue32dbfd2015-01-07 15:55:57 +08003972 for (p_cur = *pendingRequestsHook
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003973 ; p_cur != NULL
3974 ; p_cur = p_cur->p_next
3975 ) {
3976 p_cur->cancelled = 1;
3977 }
3978
Howard Sue32dbfd2015-01-07 15:55:57 +08003979 ret = pthread_mutex_unlock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003980 assert (ret == 0);
3981}
3982
3983static void processCommandsCallback(int fd, short flags, void *param) {
3984 RecordStream *p_rs;
3985 void *p_record;
3986 size_t recordlen;
3987 int ret;
Howard Sue32dbfd2015-01-07 15:55:57 +08003988 SocketListenParam *p_info = (SocketListenParam *)param;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003989
Howard Sue32dbfd2015-01-07 15:55:57 +08003990 assert(fd == p_info->fdCommand);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003991
Howard Sue32dbfd2015-01-07 15:55:57 +08003992 p_rs = p_info->p_rs;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003993
3994 for (;;) {
3995 /* loop until EAGAIN/EINTR, end of stream, or other error */
3996 ret = record_stream_get_next(p_rs, &p_record, &recordlen);
3997
3998 if (ret == 0 && p_record == NULL) {
3999 /* end-of-stream */
4000 break;
4001 } else if (ret < 0) {
4002 break;
4003 } else if (ret == 0) { /* && p_record != NULL */
Howard Sue32dbfd2015-01-07 15:55:57 +08004004 processCommandBuffer(p_record, recordlen, p_info->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004005 }
4006 }
4007
4008 if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) {
4009 /* fatal error or end-of-stream */
4010 if (ret != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004011 RLOGE("error on reading command socket errno:%d\n", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004012 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004013 RLOGW("EOS. Closing command socket.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004014 }
4015
Howard Sue32dbfd2015-01-07 15:55:57 +08004016 close(fd);
4017 p_info->fdCommand = -1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004018
Howard Sue32dbfd2015-01-07 15:55:57 +08004019 ril_event_del(p_info->commands_event);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004020
4021 record_stream_free(p_rs);
4022
4023 /* start listening for new connections again */
4024 rilEventAddWakeup(&s_listen_event);
4025
Howard Sue32dbfd2015-01-07 15:55:57 +08004026 onCommandsSocketClosed(p_info->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004027 }
4028}
4029
Howard Subd82ef12015-04-12 10:25:05 +02004030
Howard Sue32dbfd2015-01-07 15:55:57 +08004031static void onNewCommandConnect(RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004032 // Inform we are connected and the ril version
4033 int rilVer = s_callbacks.version;
Howard Sue32dbfd2015-01-07 15:55:57 +08004034 RIL_UNSOL_RESPONSE(RIL_UNSOL_RIL_CONNECTED,
4035 &rilVer, sizeof(rilVer), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004036
4037 // implicit radio state changed
Howard Sue32dbfd2015-01-07 15:55:57 +08004038 RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
4039 NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004040
4041 // Send last NITZ time data, in case it was missed
4042 if (s_lastNITZTimeData != NULL) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004043 sendResponseRaw(s_lastNITZTimeData, s_lastNITZTimeDataSize, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004044
4045 free(s_lastNITZTimeData);
4046 s_lastNITZTimeData = NULL;
4047 }
4048
4049 // Get version string
4050 if (s_callbacks.getVersion != NULL) {
4051 const char *version;
4052 version = s_callbacks.getVersion();
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004053 RLOGI("RIL Daemon version: %s\n", version);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004054
4055 property_set(PROPERTY_RIL_IMPL, version);
4056 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004057 RLOGI("RIL Daemon version: unavailable\n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004058 property_set(PROPERTY_RIL_IMPL, "unavailable");
4059 }
4060
4061}
4062
4063static void listenCallback (int fd, short flags, void *param) {
4064 int ret;
4065 int err;
4066 int is_phone_socket;
Howard Sue32dbfd2015-01-07 15:55:57 +08004067 int fdCommand = -1;
Dheeraj Shettycc231012014-07-02 21:27:57 +02004068 char* processName;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004069 RecordStream *p_rs;
Dheeraj Shettycc231012014-07-02 21:27:57 +02004070 MySocketListenParam* listenParam;
4071 RilSocket *sapSocket = NULL;
4072 socketClient *sClient = NULL;
4073
Howard Sue32dbfd2015-01-07 15:55:57 +08004074 SocketListenParam *p_info = (SocketListenParam *)param;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004075
Dheeraj Shettycc231012014-07-02 21:27:57 +02004076 if(RIL_SAP_SOCKET == p_info->type) {
4077 listenParam = (MySocketListenParam *)param;
4078 sapSocket = listenParam->socket;
4079 }
4080
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004081 struct sockaddr_un peeraddr;
4082 socklen_t socklen = sizeof (peeraddr);
4083
4084 struct ucred creds;
4085 socklen_t szCreds = sizeof(creds);
4086
4087 struct passwd *pwd = NULL;
4088
Dheeraj Shettycc231012014-07-02 21:27:57 +02004089 if(NULL == sapSocket) {
4090 assert (*p_info->fdCommand < 0);
4091 assert (fd == *p_info->fdListen);
4092 processName = PHONE_PROCESS;
4093 } else {
4094 assert (sapSocket->commandFd < 0);
4095 assert (fd == sapSocket->listenFd);
4096 processName = BLUETOOTH_PROCESS;
4097 }
4098
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004099
Howard Sue32dbfd2015-01-07 15:55:57 +08004100 fdCommand = accept(fd, (sockaddr *) &peeraddr, &socklen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004101
Howard Sue32dbfd2015-01-07 15:55:57 +08004102 if (fdCommand < 0 ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004103 RLOGE("Error on accept() errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004104 /* start listening for new connections again */
Dheeraj Shettycc231012014-07-02 21:27:57 +02004105 if(NULL == sapSocket) {
4106 rilEventAddWakeup(p_info->listen_event);
4107 } else {
4108 rilEventAddWakeup(sapSocket->getListenEvent());
4109 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004110 return;
4111 }
4112
4113 /* check the credential of the other side and only accept socket from
4114 * phone process
4115 */
4116 errno = 0;
4117 is_phone_socket = 0;
4118
Howard Sue32dbfd2015-01-07 15:55:57 +08004119 err = getsockopt(fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004120
4121 if (err == 0 && szCreds > 0) {
4122 errno = 0;
4123 pwd = getpwuid(creds.uid);
4124 if (pwd != NULL) {
Dheeraj Shettycc231012014-07-02 21:27:57 +02004125 if (strcmp(pwd->pw_name, processName) == 0) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004126 is_phone_socket = 1;
4127 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004128 RLOGE("RILD can't accept socket from process %s", pwd->pw_name);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004129 }
4130 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004131 RLOGE("Error on getpwuid() errno: %d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004132 }
4133 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004134 RLOGD("Error on getsockopt() errno: %d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004135 }
4136
Howard Subd82ef12015-04-12 10:25:05 +02004137 if (!is_phone_socket) {
Dheeraj Shettycc231012014-07-02 21:27:57 +02004138 RLOGE("RILD must accept socket from %s", processName);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004139
Dheeraj Shettycc231012014-07-02 21:27:57 +02004140 close(fdCommand);
4141 fdCommand = -1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004142
Dheeraj Shettycc231012014-07-02 21:27:57 +02004143 if(NULL == sapSocket) {
4144 onCommandsSocketClosed(p_info->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004145
Dheeraj Shettycc231012014-07-02 21:27:57 +02004146 /* start listening for new connections again */
4147 rilEventAddWakeup(p_info->listen_event);
4148 } else {
4149 sapSocket->onCommandsSocketClosed();
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004150
Dheeraj Shettycc231012014-07-02 21:27:57 +02004151 /* start listening for new connections again */
4152 rilEventAddWakeup(sapSocket->getListenEvent());
4153 }
4154
4155 return;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004156 }
4157
Howard Sue32dbfd2015-01-07 15:55:57 +08004158 ret = fcntl(fdCommand, F_SETFL, O_NONBLOCK);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004159
4160 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004161 RLOGE ("Error setting O_NONBLOCK errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004162 }
4163
Dheeraj Shettycc231012014-07-02 21:27:57 +02004164 if(NULL == sapSocket) {
4165 RLOGI("libril: new connection to %s", rilSocketIdToString(p_info->socket_id));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004166
Dheeraj Shettycc231012014-07-02 21:27:57 +02004167 p_info->fdCommand = fdCommand;
4168 p_rs = record_stream_new(p_info->fdCommand, MAX_COMMAND_BYTES);
4169 p_info->p_rs = p_rs;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004170
Dheeraj Shettycc231012014-07-02 21:27:57 +02004171 ril_event_set (p_info->commands_event, p_info->fdCommand, 1,
Howard Sue32dbfd2015-01-07 15:55:57 +08004172 p_info->processCommandsCallback, p_info);
Dheeraj Shettycc231012014-07-02 21:27:57 +02004173 rilEventAddWakeup (p_info->commands_event);
Howard Sue32dbfd2015-01-07 15:55:57 +08004174
Dheeraj Shettycc231012014-07-02 21:27:57 +02004175 onNewCommandConnect(p_info->socket_id);
4176 } else {
4177 RLOGI("libril: new connection");
Howard Sue32dbfd2015-01-07 15:55:57 +08004178
Dheeraj Shettycc231012014-07-02 21:27:57 +02004179 sapSocket->setCommandFd(fdCommand);
4180 p_rs = record_stream_new(sapSocket->getCommandFd(), MAX_COMMAND_BYTES);
4181 sClient = new socketClient(sapSocket,p_rs);
4182 ril_event_set (sapSocket->getCallbackEvent(), sapSocket->getCommandFd(), 1,
4183 sapSocket->getCommandCb(), sClient);
4184
4185 rilEventAddWakeup(sapSocket->getCallbackEvent());
4186 sapSocket->onNewCommandConnect();
4187 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004188}
4189
4190static void freeDebugCallbackArgs(int number, char **args) {
4191 for (int i = 0; i < number; i++) {
4192 if (args[i] != NULL) {
4193 free(args[i]);
4194 }
4195 }
4196 free(args);
4197}
4198
4199static void debugCallback (int fd, short flags, void *param) {
4200 int acceptFD, option;
4201 struct sockaddr_un peeraddr;
4202 socklen_t socklen = sizeof (peeraddr);
4203 int data;
4204 unsigned int qxdm_data[6];
4205 const char *deactData[1] = {"1"};
4206 char *actData[1];
4207 RIL_Dial dialData;
4208 int hangupData[1] = {1};
4209 int number;
4210 char **args;
Howard Sue32dbfd2015-01-07 15:55:57 +08004211 RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
4212 int sim_id = 0;
4213
4214 RLOGI("debugCallback for socket %s", rilSocketIdToString(socket_id));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004215
4216 acceptFD = accept (fd, (sockaddr *) &peeraddr, &socklen);
4217
4218 if (acceptFD < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004219 RLOGE ("error accepting on debug port: %d\n", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004220 return;
4221 }
4222
4223 if (recv(acceptFD, &number, sizeof(int), 0) != sizeof(int)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004224 RLOGE ("error reading on socket: number of Args: \n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004225 return;
4226 }
4227 args = (char **) malloc(sizeof(char*) * number);
4228
4229 for (int i = 0; i < number; i++) {
4230 int len;
4231 if (recv(acceptFD, &len, sizeof(int), 0) != sizeof(int)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004232 RLOGE ("error reading on socket: Len of Args: \n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004233 freeDebugCallbackArgs(i, args);
4234 return;
4235 }
4236 // +1 for null-term
4237 args[i] = (char *) malloc((sizeof(char) * len) + 1);
4238 if (recv(acceptFD, args[i], sizeof(char) * len, 0)
4239 != (int)sizeof(char) * len) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004240 RLOGE ("error reading on socket: Args[%d] \n", i);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004241 freeDebugCallbackArgs(i, args);
4242 return;
4243 }
4244 char * buf = args[i];
4245 buf[len] = 0;
Howard Sue32dbfd2015-01-07 15:55:57 +08004246 if ((i+1) == number) {
4247 /* The last argument should be sim id 0(SIM1)~3(SIM4) */
4248 sim_id = atoi(args[i]);
4249 switch (sim_id) {
4250 case 0:
4251 socket_id = RIL_SOCKET_1;
4252 break;
4253 #if (SIM_COUNT >= 2)
4254 case 1:
4255 socket_id = RIL_SOCKET_2;
4256 break;
4257 #endif
4258 #if (SIM_COUNT >= 3)
4259 case 2:
4260 socket_id = RIL_SOCKET_3;
4261 break;
4262 #endif
4263 #if (SIM_COUNT >= 4)
4264 case 3:
4265 socket_id = RIL_SOCKET_4;
4266 break;
4267 #endif
4268 default:
4269 socket_id = RIL_SOCKET_1;
4270 break;
4271 }
4272 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004273 }
4274
4275 switch (atoi(args[0])) {
4276 case 0:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004277 RLOGI ("Connection on debug port: issuing reset.");
Howard Sue32dbfd2015-01-07 15:55:57 +08004278 issueLocalRequest(RIL_REQUEST_RESET_RADIO, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004279 break;
4280 case 1:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004281 RLOGI ("Connection on debug port: issuing radio power off.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004282 data = 0;
Howard Sue32dbfd2015-01-07 15:55:57 +08004283 issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004284 // Close the socket
Howard Subd82ef12015-04-12 10:25:05 +02004285 if (socket_id == RIL_SOCKET_1 && s_ril_param_socket.fdCommand > 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004286 close(s_ril_param_socket.fdCommand);
4287 s_ril_param_socket.fdCommand = -1;
4288 }
4289 #if (SIM_COUNT == 2)
4290 else if (socket_id == RIL_SOCKET_2 && s_ril_param_socket2.fdCommand > 0) {
4291 close(s_ril_param_socket2.fdCommand);
4292 s_ril_param_socket2.fdCommand = -1;
4293 }
4294 #endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004295 break;
4296 case 2:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004297 RLOGI ("Debug port: issuing unsolicited voice network change.");
Howard Sue32dbfd2015-01-07 15:55:57 +08004298 RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004299 break;
4300 case 3:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004301 RLOGI ("Debug port: QXDM log enable.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004302 qxdm_data[0] = 65536; // head.func_tag
4303 qxdm_data[1] = 16; // head.len
4304 qxdm_data[2] = 1; // mode: 1 for 'start logging'
4305 qxdm_data[3] = 32; // log_file_size: 32megabytes
4306 qxdm_data[4] = 0; // log_mask
4307 qxdm_data[5] = 8; // log_max_fileindex
4308 issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
Howard Sue32dbfd2015-01-07 15:55:57 +08004309 6 * sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004310 break;
4311 case 4:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004312 RLOGI ("Debug port: QXDM log disable.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004313 qxdm_data[0] = 65536;
4314 qxdm_data[1] = 16;
4315 qxdm_data[2] = 0; // mode: 0 for 'stop logging'
4316 qxdm_data[3] = 32;
4317 qxdm_data[4] = 0;
4318 qxdm_data[5] = 8;
4319 issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
Howard Sue32dbfd2015-01-07 15:55:57 +08004320 6 * sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004321 break;
4322 case 5:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004323 RLOGI("Debug port: Radio On");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004324 data = 1;
Howard Sue32dbfd2015-01-07 15:55:57 +08004325 issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004326 sleep(2);
4327 // Set network selection automatic.
Howard Sue32dbfd2015-01-07 15:55:57 +08004328 issueLocalRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004329 break;
4330 case 6:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004331 RLOGI("Debug port: Setup Data Call, Apn :%s\n", args[1]);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004332 actData[0] = args[1];
4333 issueLocalRequest(RIL_REQUEST_SETUP_DATA_CALL, &actData,
Howard Sue32dbfd2015-01-07 15:55:57 +08004334 sizeof(actData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004335 break;
4336 case 7:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004337 RLOGI("Debug port: Deactivate Data Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004338 issueLocalRequest(RIL_REQUEST_DEACTIVATE_DATA_CALL, &deactData,
Howard Sue32dbfd2015-01-07 15:55:57 +08004339 sizeof(deactData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004340 break;
4341 case 8:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004342 RLOGI("Debug port: Dial Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004343 dialData.clir = 0;
4344 dialData.address = args[1];
Howard Sue32dbfd2015-01-07 15:55:57 +08004345 issueLocalRequest(RIL_REQUEST_DIAL, &dialData, sizeof(dialData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004346 break;
4347 case 9:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004348 RLOGI("Debug port: Answer Call");
Howard Sue32dbfd2015-01-07 15:55:57 +08004349 issueLocalRequest(RIL_REQUEST_ANSWER, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004350 break;
4351 case 10:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004352 RLOGI("Debug port: End Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004353 issueLocalRequest(RIL_REQUEST_HANGUP, &hangupData,
Howard Sue32dbfd2015-01-07 15:55:57 +08004354 sizeof(hangupData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004355 break;
4356 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004357 RLOGE ("Invalid request");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004358 break;
4359 }
4360 freeDebugCallbackArgs(number, args);
4361 close(acceptFD);
4362}
4363
4364
4365static void userTimerCallback (int fd, short flags, void *param) {
4366 UserCallbackInfo *p_info;
4367
4368 p_info = (UserCallbackInfo *)param;
4369
4370 p_info->p_callback(p_info->userParam);
4371
4372
4373 // FIXME generalize this...there should be a cancel mechanism
4374 if (s_last_wake_timeout_info != NULL && s_last_wake_timeout_info == p_info) {
4375 s_last_wake_timeout_info = NULL;
4376 }
4377
4378 free(p_info);
4379}
4380
4381
4382static void *
4383eventLoop(void *param) {
4384 int ret;
4385 int filedes[2];
4386
4387 ril_event_init();
4388
4389 pthread_mutex_lock(&s_startupMutex);
4390
4391 s_started = 1;
4392 pthread_cond_broadcast(&s_startupCond);
4393
4394 pthread_mutex_unlock(&s_startupMutex);
4395
4396 ret = pipe(filedes);
4397
4398 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004399 RLOGE("Error in pipe() errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004400 return NULL;
4401 }
4402
4403 s_fdWakeupRead = filedes[0];
4404 s_fdWakeupWrite = filedes[1];
4405
4406 fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
4407
4408 ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
4409 processWakeupCallback, NULL);
4410
4411 rilEventAddWakeup (&s_wakeupfd_event);
4412
4413 // Only returns on error
4414 ril_event_loop();
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004415 RLOGE ("error in event_loop_base errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004416 // kill self to restart on error
4417 kill(0, SIGKILL);
4418
4419 return NULL;
4420}
4421
4422extern "C" void
4423RIL_startEventLoop(void) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004424 /* spin up eventLoop thread and wait for it to get started */
4425 s_started = 0;
4426 pthread_mutex_lock(&s_startupMutex);
4427
Howard Sue32dbfd2015-01-07 15:55:57 +08004428 pthread_attr_t attr;
4429 pthread_attr_init(&attr);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004430 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
Howard Sue32dbfd2015-01-07 15:55:57 +08004431
4432 int result = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
4433 if (result != 0) {
4434 RLOGE("Failed to create dispatch thread: %s", strerror(result));
4435 goto done;
4436 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004437
4438 while (s_started == 0) {
4439 pthread_cond_wait(&s_startupCond, &s_startupMutex);
4440 }
4441
Howard Sue32dbfd2015-01-07 15:55:57 +08004442done:
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004443 pthread_mutex_unlock(&s_startupMutex);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004444}
4445
4446// Used for testing purpose only.
4447extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) {
4448 memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
4449}
4450
Howard Sue32dbfd2015-01-07 15:55:57 +08004451static void startListen(RIL_SOCKET_ID socket_id, SocketListenParam* socket_listen_p) {
4452 int fdListen = -1;
4453 int ret;
4454 char socket_name[10];
4455
4456 memset(socket_name, 0, sizeof(char)*10);
4457
4458 switch(socket_id) {
4459 case RIL_SOCKET_1:
4460 strncpy(socket_name, RIL_getRilSocketName(), 9);
4461 break;
4462 #if (SIM_COUNT >= 2)
4463 case RIL_SOCKET_2:
4464 strncpy(socket_name, SOCKET2_NAME_RIL, 9);
4465 break;
4466 #endif
4467 #if (SIM_COUNT >= 3)
4468 case RIL_SOCKET_3:
4469 strncpy(socket_name, SOCKET3_NAME_RIL, 9);
4470 break;
4471 #endif
4472 #if (SIM_COUNT >= 4)
4473 case RIL_SOCKET_4:
4474 strncpy(socket_name, SOCKET4_NAME_RIL, 9);
4475 break;
4476 #endif
4477 default:
4478 RLOGE("Socket id is wrong!!");
4479 return;
4480 }
4481
4482 RLOGI("Start to listen %s", rilSocketIdToString(socket_id));
4483
4484 fdListen = android_get_control_socket(socket_name);
4485 if (fdListen < 0) {
4486 RLOGE("Failed to get socket %s", socket_name);
4487 exit(-1);
4488 }
4489
4490 ret = listen(fdListen, 4);
4491
4492 if (ret < 0) {
4493 RLOGE("Failed to listen on control socket '%d': %s",
4494 fdListen, strerror(errno));
4495 exit(-1);
4496 }
4497 socket_listen_p->fdListen = fdListen;
4498
4499 /* note: non-persistent so we can accept only one connection at a time */
4500 ril_event_set (socket_listen_p->listen_event, fdListen, false,
4501 listenCallback, socket_listen_p);
4502
4503 rilEventAddWakeup (socket_listen_p->listen_event);
4504}
4505
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004506extern "C" void
4507RIL_register (const RIL_RadioFunctions *callbacks) {
4508 int ret;
4509 int flags;
4510
Howard Sue32dbfd2015-01-07 15:55:57 +08004511 RLOGI("SIM_COUNT: %d", SIM_COUNT);
4512
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004513 if (callbacks == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004514 RLOGE("RIL_register: RIL_RadioFunctions * null");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004515 return;
4516 }
4517 if (callbacks->version < RIL_VERSION_MIN) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004518 RLOGE("RIL_register: version %d is to old, min version is %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004519 callbacks->version, RIL_VERSION_MIN);
4520 return;
4521 }
Sanket Padawe9343e872016-01-11 12:45:43 -08004522
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004523 RLOGE("RIL_register: RIL version %d", callbacks->version);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004524
4525 if (s_registerCalled > 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004526 RLOGE("RIL_register has been called more than once. "
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004527 "Subsequent call ignored");
4528 return;
4529 }
4530
4531 memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
4532
Howard Sue32dbfd2015-01-07 15:55:57 +08004533 /* Initialize socket1 parameters */
4534 s_ril_param_socket = {
4535 RIL_SOCKET_1, /* socket_id */
4536 -1, /* fdListen */
4537 -1, /* fdCommand */
4538 PHONE_PROCESS, /* processName */
4539 &s_commands_event, /* commands_event */
4540 &s_listen_event, /* listen_event */
4541 processCommandsCallback, /* processCommandsCallback */
4542 NULL /* p_rs */
4543 };
4544
4545#if (SIM_COUNT >= 2)
4546 s_ril_param_socket2 = {
4547 RIL_SOCKET_2, /* socket_id */
4548 -1, /* fdListen */
4549 -1, /* fdCommand */
4550 PHONE_PROCESS, /* processName */
4551 &s_commands_event_socket2, /* commands_event */
4552 &s_listen_event_socket2, /* listen_event */
4553 processCommandsCallback, /* processCommandsCallback */
4554 NULL /* p_rs */
4555 };
4556#endif
4557
4558#if (SIM_COUNT >= 3)
4559 s_ril_param_socket3 = {
4560 RIL_SOCKET_3, /* socket_id */
4561 -1, /* fdListen */
4562 -1, /* fdCommand */
4563 PHONE_PROCESS, /* processName */
4564 &s_commands_event_socket3, /* commands_event */
4565 &s_listen_event_socket3, /* listen_event */
4566 processCommandsCallback, /* processCommandsCallback */
4567 NULL /* p_rs */
4568 };
4569#endif
4570
4571#if (SIM_COUNT >= 4)
4572 s_ril_param_socket4 = {
4573 RIL_SOCKET_4, /* socket_id */
4574 -1, /* fdListen */
4575 -1, /* fdCommand */
4576 PHONE_PROCESS, /* processName */
4577 &s_commands_event_socket4, /* commands_event */
4578 &s_listen_event_socket4, /* listen_event */
4579 processCommandsCallback, /* processCommandsCallback */
4580 NULL /* p_rs */
4581 };
4582#endif
4583
Howard Subd82ef12015-04-12 10:25:05 +02004584
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004585 s_registerCalled = 1;
4586
Howard Sue32dbfd2015-01-07 15:55:57 +08004587 RLOGI("s_registerCalled flag set, %d", s_started);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004588 // Little self-check
4589
4590 for (int i = 0; i < (int)NUM_ELEMS(s_commands); i++) {
4591 assert(i == s_commands[i].requestNumber);
4592 }
4593
Howard Subd82ef12015-04-12 10:25:05 +02004594 for (int i = 0; i < (int)NUM_ELEMS(s_commands_v); i++) {
4595 assert(i + RIL_VENDOR_COMMANDS_OFFSET == s_commands[i].requestNumber);
4596 }
4597
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004598 for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses); i++) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004599 assert(i + RIL_UNSOL_RESPONSE_BASE
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004600 == s_unsolResponses[i].requestNumber);
4601 }
4602
Howard Subd82ef12015-04-12 10:25:05 +02004603 for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses_v); i++) {
4604 assert(i + RIL_UNSOL_RESPONSE_BASE + RIL_VENDOR_COMMANDS_OFFSET
4605 == s_unsolResponses[i].requestNumber);
4606 }
4607
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004608 // New rild impl calls RIL_startEventLoop() first
4609 // old standalone impl wants it here.
4610
4611 if (s_started == 0) {
4612 RIL_startEventLoop();
4613 }
4614
Howard Sue32dbfd2015-01-07 15:55:57 +08004615 // start listen socket1
4616 startListen(RIL_SOCKET_1, &s_ril_param_socket);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004617
Howard Sue32dbfd2015-01-07 15:55:57 +08004618#if (SIM_COUNT >= 2)
4619 // start listen socket2
4620 startListen(RIL_SOCKET_2, &s_ril_param_socket2);
4621#endif /* (SIM_COUNT == 2) */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004622
Howard Sue32dbfd2015-01-07 15:55:57 +08004623#if (SIM_COUNT >= 3)
4624 // start listen socket3
4625 startListen(RIL_SOCKET_3, &s_ril_param_socket3);
4626#endif /* (SIM_COUNT == 3) */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004627
Howard Sue32dbfd2015-01-07 15:55:57 +08004628#if (SIM_COUNT >= 4)
4629 // start listen socket4
4630 startListen(RIL_SOCKET_4, &s_ril_param_socket4);
4631#endif /* (SIM_COUNT == 4) */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004632
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004633
4634#if 1
4635 // start debug interface socket
4636
Howard Sue32dbfd2015-01-07 15:55:57 +08004637 char *inst = NULL;
4638 if (strlen(RIL_getRilSocketName()) >= strlen(SOCKET_NAME_RIL)) {
4639 inst = RIL_getRilSocketName() + strlen(SOCKET_NAME_RIL);
4640 }
4641
4642 char rildebug[MAX_DEBUG_SOCKET_NAME_LENGTH] = SOCKET_NAME_RIL_DEBUG;
4643 if (inst != NULL) {
Andreas Schneider3063dc12015-04-13 23:04:05 +02004644 snprintf(rildebug, sizeof(rildebug), "%s%s", SOCKET_NAME_RIL_DEBUG, inst);
Howard Sue32dbfd2015-01-07 15:55:57 +08004645 }
4646
4647 s_fdDebug = android_get_control_socket(rildebug);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004648 if (s_fdDebug < 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004649 RLOGE("Failed to get socket : %s errno:%d", rildebug, errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004650 exit(-1);
4651 }
4652
4653 ret = listen(s_fdDebug, 4);
4654
4655 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004656 RLOGE("Failed to listen on ril debug socket '%d': %s",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004657 s_fdDebug, strerror(errno));
4658 exit(-1);
4659 }
4660
4661 ril_event_set (&s_debug_event, s_fdDebug, true,
4662 debugCallback, NULL);
4663
4664 rilEventAddWakeup (&s_debug_event);
4665#endif
4666
4667}
4668
Dheeraj Shettycc231012014-07-02 21:27:57 +02004669extern "C" void
4670RIL_register_socket (RIL_RadioFunctions *(*Init)(const struct RIL_Env *, int, char **),RIL_SOCKET_TYPE socketType, int argc, char **argv) {
4671
4672 RIL_RadioFunctions* UimFuncs = NULL;
4673
4674 if(Init) {
4675 UimFuncs = Init(&RilSapSocket::uimRilEnv, argc, argv);
4676
4677 switch(socketType) {
4678 case RIL_SAP_SOCKET:
4679 RilSapSocket::initSapSocket("sap_uim_socket1", UimFuncs);
4680
4681#if (SIM_COUNT >= 2)
4682 RilSapSocket::initSapSocket("sap_uim_socket2", UimFuncs);
4683#endif
4684
4685#if (SIM_COUNT >= 3)
4686 RilSapSocket::initSapSocket("sap_uim_socket3", UimFuncs);
4687#endif
4688
4689#if (SIM_COUNT >= 4)
4690 RilSapSocket::initSapSocket("sap_uim_socket4", UimFuncs);
4691#endif
4692 }
4693 }
4694}
4695
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004696static int
4697checkAndDequeueRequestInfo(struct RequestInfo *pRI) {
4698 int ret = 0;
Howard Sue32dbfd2015-01-07 15:55:57 +08004699 /* Hook for current context
4700 pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
4701 pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
4702 /* pendingRequestsHook refer to &s_pendingRequests */
4703 RequestInfo ** pendingRequestsHook = &s_pendingRequests;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004704
4705 if (pRI == NULL) {
4706 return 0;
4707 }
4708
Howard Sue32dbfd2015-01-07 15:55:57 +08004709#if (SIM_COUNT >= 2)
4710 if (pRI->socket_id == RIL_SOCKET_2) {
4711 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
4712 pendingRequestsHook = &s_pendingRequests_socket2;
4713 }
4714#if (SIM_COUNT >= 3)
4715 if (pRI->socket_id == RIL_SOCKET_3) {
4716 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
4717 pendingRequestsHook = &s_pendingRequests_socket3;
4718 }
4719#endif
4720#if (SIM_COUNT >= 4)
4721 if (pRI->socket_id == RIL_SOCKET_4) {
4722 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
4723 pendingRequestsHook = &s_pendingRequests_socket4;
4724 }
4725#endif
4726#endif
4727 pthread_mutex_lock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004728
Howard Sue32dbfd2015-01-07 15:55:57 +08004729 for(RequestInfo **ppCur = pendingRequestsHook
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004730 ; *ppCur != NULL
4731 ; ppCur = &((*ppCur)->p_next)
4732 ) {
4733 if (pRI == *ppCur) {
4734 ret = 1;
4735
4736 *ppCur = (*ppCur)->p_next;
4737 break;
4738 }
4739 }
4740
Howard Sue32dbfd2015-01-07 15:55:57 +08004741 pthread_mutex_unlock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004742
4743 return ret;
4744}
4745
4746
4747extern "C" void
4748RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
4749 RequestInfo *pRI;
4750 int ret;
Howard Sue32dbfd2015-01-07 15:55:57 +08004751 int fd = s_ril_param_socket.fdCommand;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004752 size_t errorOffset;
Howard Sue32dbfd2015-01-07 15:55:57 +08004753 RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004754
4755 pRI = (RequestInfo *)t;
4756
4757 if (!checkAndDequeueRequestInfo(pRI)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004758 RLOGE ("RIL_onRequestComplete: invalid RIL_Token");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004759 return;
4760 }
4761
Howard Sue32dbfd2015-01-07 15:55:57 +08004762 socket_id = pRI->socket_id;
4763#if (SIM_COUNT >= 2)
4764 if (socket_id == RIL_SOCKET_2) {
4765 fd = s_ril_param_socket2.fdCommand;
4766 }
4767#if (SIM_COUNT >= 3)
4768 if (socket_id == RIL_SOCKET_3) {
4769 fd = s_ril_param_socket3.fdCommand;
4770 }
4771#endif
4772#if (SIM_COUNT >= 4)
4773 if (socket_id == RIL_SOCKET_4) {
4774 fd = s_ril_param_socket4.fdCommand;
4775 }
4776#endif
4777#endif
Robert Greenwaltbc29c432015-04-29 16:57:39 -07004778#if VDBG
Howard Sue32dbfd2015-01-07 15:55:57 +08004779 RLOGD("RequestComplete, %s", rilSocketIdToString(socket_id));
Robert Greenwaltbc29c432015-04-29 16:57:39 -07004780#endif
Howard Sue32dbfd2015-01-07 15:55:57 +08004781
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004782 if (pRI->local > 0) {
4783 // Locally issued command...void only!
4784 // response does not go back up the command socket
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004785 RLOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004786
4787 goto done;
4788 }
4789
4790 appendPrintBuf("[%04d]< %s",
4791 pRI->token, requestToString(pRI->pCI->requestNumber));
4792
4793 if (pRI->cancelled == 0) {
4794 Parcel p;
4795
4796 p.writeInt32 (RESPONSE_SOLICITED);
4797 p.writeInt32 (pRI->token);
4798 errorOffset = p.dataPosition();
4799
4800 p.writeInt32 (e);
4801
4802 if (response != NULL) {
4803 // there is a response payload, no matter success or not.
4804 ret = pRI->pCI->responseFunction(p, response, responselen);
4805
4806 /* if an error occurred, rewind and mark it */
4807 if (ret != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004808 RLOGE ("responseFunction error, ret %d", ret);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004809 p.setDataPosition(errorOffset);
4810 p.writeInt32 (ret);
4811 }
4812 }
4813
4814 if (e != RIL_E_SUCCESS) {
4815 appendPrintBuf("%s fails by %s", printBuf, failCauseToString(e));
4816 }
4817
Howard Sue32dbfd2015-01-07 15:55:57 +08004818 if (fd < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004819 RLOGD ("RIL onRequestComplete: Command channel closed");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004820 }
Howard Sue32dbfd2015-01-07 15:55:57 +08004821 sendResponse(p, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004822 }
4823
4824done:
4825 free(pRI);
4826}
4827
Howard Subd82ef12015-04-12 10:25:05 +02004828
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004829static void
4830grabPartialWakeLock() {
4831 acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
4832}
4833
4834static void
4835releaseWakeLock() {
4836 release_wake_lock(ANDROID_WAKE_LOCK_NAME);
4837}
4838
4839/**
4840 * Timer callback to put us back to sleep before the default timeout
4841 */
4842static void
4843wakeTimeoutCallback (void *param) {
4844 // We're using "param != NULL" as a cancellation mechanism
4845 if (param == NULL) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004846 releaseWakeLock();
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004847 }
4848}
4849
4850static int
4851decodeVoiceRadioTechnology (RIL_RadioState radioState) {
4852 switch (radioState) {
4853 case RADIO_STATE_SIM_NOT_READY:
4854 case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
4855 case RADIO_STATE_SIM_READY:
4856 return RADIO_TECH_UMTS;
4857
4858 case RADIO_STATE_RUIM_NOT_READY:
4859 case RADIO_STATE_RUIM_READY:
4860 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
4861 case RADIO_STATE_NV_NOT_READY:
4862 case RADIO_STATE_NV_READY:
4863 return RADIO_TECH_1xRTT;
4864
4865 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004866 RLOGD("decodeVoiceRadioTechnology: Invoked with incorrect RadioState");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004867 return -1;
4868 }
4869}
4870
4871static int
4872decodeCdmaSubscriptionSource (RIL_RadioState radioState) {
4873 switch (radioState) {
4874 case RADIO_STATE_SIM_NOT_READY:
4875 case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
4876 case RADIO_STATE_SIM_READY:
4877 case RADIO_STATE_RUIM_NOT_READY:
4878 case RADIO_STATE_RUIM_READY:
4879 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
4880 return CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM;
4881
4882 case RADIO_STATE_NV_NOT_READY:
4883 case RADIO_STATE_NV_READY:
4884 return CDMA_SUBSCRIPTION_SOURCE_NV;
4885
4886 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004887 RLOGD("decodeCdmaSubscriptionSource: Invoked with incorrect RadioState");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004888 return -1;
4889 }
4890}
4891
4892static int
4893decodeSimStatus (RIL_RadioState radioState) {
4894 switch (radioState) {
4895 case RADIO_STATE_SIM_NOT_READY:
4896 case RADIO_STATE_RUIM_NOT_READY:
4897 case RADIO_STATE_NV_NOT_READY:
4898 case RADIO_STATE_NV_READY:
4899 return -1;
4900 case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
4901 case RADIO_STATE_SIM_READY:
4902 case RADIO_STATE_RUIM_READY:
4903 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
4904 return radioState;
4905 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004906 RLOGD("decodeSimStatus: Invoked with incorrect RadioState");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004907 return -1;
4908 }
4909}
4910
4911static bool is3gpp2(int radioTech) {
4912 switch (radioTech) {
4913 case RADIO_TECH_IS95A:
4914 case RADIO_TECH_IS95B:
4915 case RADIO_TECH_1xRTT:
4916 case RADIO_TECH_EVDO_0:
4917 case RADIO_TECH_EVDO_A:
4918 case RADIO_TECH_EVDO_B:
4919 case RADIO_TECH_EHRPD:
4920 return true;
4921 default:
4922 return false;
4923 }
4924}
4925
4926/* If RIL sends SIM states or RUIM states, store the voice radio
4927 * technology and subscription source information so that they can be
4928 * returned when telephony framework requests them
4929 */
4930static RIL_RadioState
Howard Subd82ef12015-04-12 10:25:05 +02004931processRadioState(RIL_RadioState newRadioState, RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004932
4933 if((newRadioState > RADIO_STATE_UNAVAILABLE) && (newRadioState < RADIO_STATE_ON)) {
4934 int newVoiceRadioTech;
4935 int newCdmaSubscriptionSource;
4936 int newSimStatus;
4937
4938 /* This is old RIL. Decode Subscription source and Voice Radio Technology
4939 from Radio State and send change notifications if there has been a change */
4940 newVoiceRadioTech = decodeVoiceRadioTechnology(newRadioState);
4941 if(newVoiceRadioTech != voiceRadioTech) {
4942 voiceRadioTech = newVoiceRadioTech;
Howard Sue32dbfd2015-01-07 15:55:57 +08004943 RIL_UNSOL_RESPONSE(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED,
4944 &voiceRadioTech, sizeof(voiceRadioTech), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004945 }
4946 if(is3gpp2(newVoiceRadioTech)) {
4947 newCdmaSubscriptionSource = decodeCdmaSubscriptionSource(newRadioState);
4948 if(newCdmaSubscriptionSource != cdmaSubscriptionSource) {
4949 cdmaSubscriptionSource = newCdmaSubscriptionSource;
Howard Sue32dbfd2015-01-07 15:55:57 +08004950 RIL_UNSOL_RESPONSE(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED,
4951 &cdmaSubscriptionSource, sizeof(cdmaSubscriptionSource), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004952 }
4953 }
4954 newSimStatus = decodeSimStatus(newRadioState);
4955 if(newSimStatus != simRuimStatus) {
4956 simRuimStatus = newSimStatus;
Howard Sue32dbfd2015-01-07 15:55:57 +08004957 RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004958 }
4959
4960 /* Send RADIO_ON to telephony */
4961 newRadioState = RADIO_STATE_ON;
4962 }
4963
4964 return newRadioState;
4965}
4966
Howard Subd82ef12015-04-12 10:25:05 +02004967
Howard Sue32dbfd2015-01-07 15:55:57 +08004968#if defined(ANDROID_MULTI_SIM)
4969extern "C"
Andreas Schneider47b2d962015-04-13 22:54:49 +02004970void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
Howard Sue32dbfd2015-01-07 15:55:57 +08004971 size_t datalen, RIL_SOCKET_ID socket_id)
4972#else
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004973extern "C"
Andreas Schneider47b2d962015-04-13 22:54:49 +02004974void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004975 size_t datalen)
Howard Sue32dbfd2015-01-07 15:55:57 +08004976#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004977{
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004978 int ret;
4979 int64_t timeReceived = 0;
4980 bool shouldScheduleTimeout = false;
4981 RIL_RadioState newState;
Howard Sue32dbfd2015-01-07 15:55:57 +08004982 RIL_SOCKET_ID soc_id = RIL_SOCKET_1;
Howard Subd82ef12015-04-12 10:25:05 +02004983 UnsolResponseInfo *pRI = NULL;
Howard Sue32dbfd2015-01-07 15:55:57 +08004984
4985#if defined(ANDROID_MULTI_SIM)
4986 soc_id = socket_id;
4987#endif
4988
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004989
4990 if (s_registerCalled == 0) {
4991 // Ignore RIL_onUnsolicitedResponse before RIL_register
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004992 RLOGW("RIL_onUnsolicitedResponse called before RIL_register");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004993 return;
4994 }
Howard Sue32dbfd2015-01-07 15:55:57 +08004995
Howard Subd82ef12015-04-12 10:25:05 +02004996 /* Hack to include Samsung responses */
4997 if (unsolResponse > RIL_VENDOR_COMMANDS_OFFSET + RIL_UNSOL_RESPONSE_BASE) {
4998 int index = unsolResponse - RIL_VENDOR_COMMANDS_OFFSET - RIL_UNSOL_RESPONSE_BASE;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004999
Howard Subd82ef12015-04-12 10:25:05 +02005000 RLOGD("SAMSUNG: unsolResponse=%d, unsolResponseIndex=%d", unsolResponse, index);
5001
5002 if (index < (int32_t)NUM_ELEMS(s_unsolResponses_v))
5003 pRI = &s_unsolResponses_v[index];
5004 } else {
5005 int index = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
5006 if (index < (int32_t)NUM_ELEMS(s_unsolResponses))
5007 pRI = &s_unsolResponses[index];
5008 }
5009
5010 if (pRI == NULL || pRI->responseFunction == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02005011 RLOGE("unsupported unsolicited response code %d", unsolResponse);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005012 return;
5013 }
5014
5015 // Grab a wake lock if needed for this reponse,
5016 // as we exit we'll either release it immediately
5017 // or set a timer to release it later.
Howard Subd82ef12015-04-12 10:25:05 +02005018 switch (pRI->wakeType) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005019 case WAKE_PARTIAL:
5020 grabPartialWakeLock();
5021 shouldScheduleTimeout = true;
5022 break;
5023
5024 case DONT_WAKE:
5025 default:
5026 // No wake lock is grabed so don't set timeout
5027 shouldScheduleTimeout = false;
5028 break;
5029 }
5030
5031 // Mark the time this was received, doing this
5032 // after grabing the wakelock incase getting
5033 // the elapsedRealTime might cause us to goto
5034 // sleep.
5035 if (unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
5036 timeReceived = elapsedRealtime();
5037 }
5038
5039 appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
5040
5041 Parcel p;
5042
5043 p.writeInt32 (RESPONSE_UNSOLICITED);
5044 p.writeInt32 (unsolResponse);
5045
Howard Subd82ef12015-04-12 10:25:05 +02005046 ret = pRI->responseFunction(p, const_cast<void*>(data), datalen);
5047
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005048 if (ret != 0) {
5049 // Problem with the response. Don't continue;
5050 goto error_exit;
5051 }
5052
5053 // some things get more payload
5054 switch(unsolResponse) {
5055 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
Howard Sue32dbfd2015-01-07 15:55:57 +08005056 newState = processRadioState(CALL_ONSTATEREQUEST(soc_id), soc_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005057 p.writeInt32(newState);
5058 appendPrintBuf("%s {%s}", printBuf,
Howard Sue32dbfd2015-01-07 15:55:57 +08005059 radioStateToString(CALL_ONSTATEREQUEST(soc_id)));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005060 break;
5061
5062
5063 case RIL_UNSOL_NITZ_TIME_RECEIVED:
5064 // Store the time that this was received so the
5065 // handler of this message can account for
5066 // the time it takes to arrive and process. In
5067 // particular the system has been known to sleep
5068 // before this message can be processed.
5069 p.writeInt64(timeReceived);
5070 break;
5071 }
5072
Robert Greenwaltbc29c432015-04-29 16:57:39 -07005073#if VDBG
Howard Sue32dbfd2015-01-07 15:55:57 +08005074 RLOGI("%s UNSOLICITED: %s length:%d", rilSocketIdToString(soc_id), requestToString(unsolResponse), p.dataSize());
Robert Greenwaltbc29c432015-04-29 16:57:39 -07005075#endif
Howard Sue32dbfd2015-01-07 15:55:57 +08005076 ret = sendResponse(p, soc_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005077 if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
5078
5079 // Unfortunately, NITZ time is not poll/update like everything
5080 // else in the system. So, if the upstream client isn't connected,
5081 // keep a copy of the last NITZ response (with receive time noted
5082 // above) around so we can deliver it when it is connected
5083
5084 if (s_lastNITZTimeData != NULL) {
5085 free (s_lastNITZTimeData);
5086 s_lastNITZTimeData = NULL;
5087 }
5088
5089 s_lastNITZTimeData = malloc(p.dataSize());
5090 s_lastNITZTimeDataSize = p.dataSize();
5091 memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
5092 }
5093
5094 // For now, we automatically go back to sleep after TIMEVAL_WAKE_TIMEOUT
5095 // FIXME The java code should handshake here to release wake lock
5096
5097 if (shouldScheduleTimeout) {
5098 // Cancel the previous request
5099 if (s_last_wake_timeout_info != NULL) {
5100 s_last_wake_timeout_info->userParam = (void *)1;
5101 }
5102
5103 s_last_wake_timeout_info
5104 = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
5105 &TIMEVAL_WAKE_TIMEOUT);
5106 }
5107
5108 // Normal exit
5109 return;
5110
5111error_exit:
5112 if (shouldScheduleTimeout) {
5113 releaseWakeLock();
5114 }
5115}
5116
5117/** FIXME generalize this if you track UserCAllbackInfo, clear it
5118 when the callback occurs
5119*/
5120static UserCallbackInfo *
5121internalRequestTimedCallback (RIL_TimedCallback callback, void *param,
5122 const struct timeval *relativeTime)
5123{
5124 struct timeval myRelativeTime;
5125 UserCallbackInfo *p_info;
5126
5127 p_info = (UserCallbackInfo *) malloc (sizeof(UserCallbackInfo));
5128
5129 p_info->p_callback = callback;
5130 p_info->userParam = param;
5131
5132 if (relativeTime == NULL) {
5133 /* treat null parameter as a 0 relative time */
5134 memset (&myRelativeTime, 0, sizeof(myRelativeTime));
5135 } else {
5136 /* FIXME I think event_add's tv param is really const anyway */
5137 memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime));
5138 }
5139
5140 ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info);
5141
5142 ril_timer_add(&(p_info->event), &myRelativeTime);
5143
5144 triggerEvLoop();
5145 return p_info;
5146}
5147
5148
5149extern "C" void
5150RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
5151 const struct timeval *relativeTime) {
5152 internalRequestTimedCallback (callback, param, relativeTime);
5153}
5154
5155const char *
5156failCauseToString(RIL_Errno e) {
5157 switch(e) {
5158 case RIL_E_SUCCESS: return "E_SUCCESS";
XpLoDWilDba5c6a32013-07-27 21:12:19 +02005159 case RIL_E_RADIO_NOT_AVAILABLE: return "E_RADIO_NOT_AVAILABLE";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005160 case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE";
5161 case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT";
5162 case RIL_E_SIM_PIN2: return "E_SIM_PIN2";
5163 case RIL_E_SIM_PUK2: return "E_SIM_PUK2";
5164 case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED";
5165 case RIL_E_CANCELLED: return "E_CANCELLED";
5166 case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL";
5167 case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW";
5168 case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY";
5169 case RIL_E_SIM_ABSENT:return "E_SIM_ABSENT";
5170 case RIL_E_ILLEGAL_SIM_OR_ME:return "E_ILLEGAL_SIM_OR_ME";
5171#ifdef FEATURE_MULTIMODE_ANDROID
5172 case RIL_E_SUBSCRIPTION_NOT_AVAILABLE:return "E_SUBSCRIPTION_NOT_AVAILABLE";
5173 case RIL_E_MODE_NOT_SUPPORTED:return "E_MODE_NOT_SUPPORTED";
5174#endif
5175 default: return "<unknown error>";
5176 }
5177}
5178
5179const char *
5180radioStateToString(RIL_RadioState s) {
5181 switch(s) {
5182 case RADIO_STATE_OFF: return "RADIO_OFF";
5183 case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE";
5184 case RADIO_STATE_SIM_NOT_READY: return "RADIO_SIM_NOT_READY";
5185 case RADIO_STATE_SIM_LOCKED_OR_ABSENT: return "RADIO_SIM_LOCKED_OR_ABSENT";
5186 case RADIO_STATE_SIM_READY: return "RADIO_SIM_READY";
5187 case RADIO_STATE_RUIM_NOT_READY:return"RADIO_RUIM_NOT_READY";
5188 case RADIO_STATE_RUIM_READY:return"RADIO_RUIM_READY";
5189 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:return"RADIO_RUIM_LOCKED_OR_ABSENT";
5190 case RADIO_STATE_NV_NOT_READY:return"RADIO_NV_NOT_READY";
5191 case RADIO_STATE_NV_READY:return"RADIO_NV_READY";
5192 case RADIO_STATE_ON:return"RADIO_ON";
5193 default: return "<unknown state>";
5194 }
5195}
5196
5197const char *
5198callStateToString(RIL_CallState s) {
5199 switch(s) {
5200 case RIL_CALL_ACTIVE : return "ACTIVE";
5201 case RIL_CALL_HOLDING: return "HOLDING";
5202 case RIL_CALL_DIALING: return "DIALING";
5203 case RIL_CALL_ALERTING: return "ALERTING";
5204 case RIL_CALL_INCOMING: return "INCOMING";
5205 case RIL_CALL_WAITING: return "WAITING";
5206 default: return "<unknown state>";
5207 }
5208}
5209
5210const char *
5211requestToString(int request) {
5212/*
5213 cat libs/telephony/ril_commands.h \
5214 | egrep "^ *{RIL_" \
5215 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
5216
5217
5218 cat libs/telephony/ril_unsol_commands.h \
5219 | egrep "^ *{RIL_" \
5220 | sed -re 's/\{RIL_([^,]+),([^}]+).+/case RIL_\1: return "\1";/'
5221
5222*/
5223 switch(request) {
5224 case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
5225 case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
5226 case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
5227 case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
5228 case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
5229 case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
5230 case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
5231 case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
5232 case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
5233 case RIL_REQUEST_DIAL: return "DIAL";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005234 case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
5235 case RIL_REQUEST_HANGUP: return "HANGUP";
5236 case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
5237 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
5238 case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
5239 case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
5240 case RIL_REQUEST_UDUB: return "UDUB";
5241 case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
5242 case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
5243 case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
5244 case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
5245 case RIL_REQUEST_OPERATOR: return "OPERATOR";
5246 case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
5247 case RIL_REQUEST_DTMF: return "DTMF";
5248 case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
5249 case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
5250 case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
5251 case RIL_REQUEST_SIM_IO: return "SIM_IO";
5252 case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
5253 case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
5254 case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
5255 case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
5256 case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
5257 case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
5258 case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
5259 case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
5260 case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
5261 case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
5262 case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
5263 case RIL_REQUEST_ANSWER: return "ANSWER";
5264 case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
5265 case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
5266 case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
5267 case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
5268 case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
5269 case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
5270 case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
5271 case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
5272 case RIL_REQUEST_DTMF_START: return "DTMF_START";
5273 case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
5274 case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
5275 case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
5276 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE";
5277 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE";
5278 case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS";
5279 case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
5280 case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
5281 case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
5282 case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
5283 case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
5284 case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
5285 case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
5286 case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
5287 case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
5288 case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
5289 case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE";
5290 case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE";
5291 case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND";
5292 case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE";
5293 case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
5294 case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
5295 case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER";
5296 case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES";
XpLoDWilDba5c6a32013-07-27 21:12:19 +02005297 case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:return"CDMA_SET_SUBSCRIPTION_SOURCE";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005298 case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:return"CDMA_SET_ROAMING_PREFERENCE";
5299 case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:return"CDMA_QUERY_ROAMING_PREFERENCE";
5300 case RIL_REQUEST_SET_TTY_MODE:return"SET_TTY_MODE";
5301 case RIL_REQUEST_QUERY_TTY_MODE:return"QUERY_TTY_MODE";
5302 case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
5303 case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
5304 case RIL_REQUEST_CDMA_FLASH:return"CDMA_FLASH";
5305 case RIL_REQUEST_CDMA_BURST_DTMF:return"CDMA_BURST_DTMF";
5306 case RIL_REQUEST_CDMA_SEND_SMS:return"CDMA_SEND_SMS";
5307 case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:return"CDMA_SMS_ACKNOWLEDGE";
5308 case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG:return"GSM_GET_BROADCAST_SMS_CONFIG";
5309 case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG:return"GSM_SET_BROADCAST_SMS_CONFIG";
5310 case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG:return "CDMA_GET_BROADCAST_SMS_CONFIG";
5311 case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG:return "CDMA_SET_BROADCAST_SMS_CONFIG";
5312 case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION:return "CDMA_SMS_BROADCAST_ACTIVATION";
Ethan Chend6e30652013-08-04 22:49:56 -07005313 case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return"CDMA_VALIDATE_AND_WRITE_AKEY";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005314 case RIL_REQUEST_CDMA_SUBSCRIPTION: return"CDMA_SUBSCRIPTION";
5315 case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "CDMA_WRITE_SMS_TO_RUIM";
5316 case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "CDMA_DELETE_SMS_ON_RUIM";
5317 case RIL_REQUEST_DEVICE_IDENTITY: return "DEVICE_IDENTITY";
5318 case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "EXIT_EMERGENCY_CALLBACK_MODE";
5319 case RIL_REQUEST_GET_SMSC_ADDRESS: return "GET_SMSC_ADDRESS";
5320 case RIL_REQUEST_SET_SMSC_ADDRESS: return "SET_SMSC_ADDRESS";
5321 case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "REPORT_SMS_MEMORY_STATUS";
5322 case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "REPORT_STK_SERVICE_IS_RUNNING";
5323 case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "CDMA_GET_SUBSCRIPTION_SOURCE";
5324 case RIL_REQUEST_ISIM_AUTHENTICATION: return "ISIM_AUTHENTICATION";
5325 case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
5326 case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
5327 case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH";
Ajay Nambie63b4f62011-11-15 11:19:30 -08005328 case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM";
XpLoDWilDba5c6a32013-07-27 21:12:19 +02005329 case RIL_REQUEST_GET_CELL_INFO_LIST: return"GET_CELL_INFO_LIST";
5330 case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return"SET_UNSOL_CELL_INFO_LIST_RATE";
Andrew Jiangca4a9a02014-01-18 18:04:08 -05005331 case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "RIL_REQUEST_SET_INITIAL_ATTACH_APN";
5332 case RIL_REQUEST_IMS_REGISTRATION_STATE: return "IMS_REGISTRATION_STATE";
5333 case RIL_REQUEST_IMS_SEND_SMS: return "IMS_SEND_SMS";
Howard Sue32dbfd2015-01-07 15:55:57 +08005334 case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC: return "SIM_TRANSMIT_APDU_BASIC";
5335 case RIL_REQUEST_SIM_OPEN_CHANNEL: return "SIM_OPEN_CHANNEL";
5336 case RIL_REQUEST_SIM_CLOSE_CHANNEL: return "SIM_CLOSE_CHANNEL";
5337 case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL: return "SIM_TRANSMIT_APDU_CHANNEL";
Howard Subd82ef12015-04-12 10:25:05 +02005338 case RIL_REQUEST_GET_RADIO_CAPABILITY: return "RIL_REQUEST_GET_RADIO_CAPABILITY";
5339 case RIL_REQUEST_SET_RADIO_CAPABILITY: return "RIL_REQUEST_SET_RADIO_CAPABILITY";
Howard Sue32dbfd2015-01-07 15:55:57 +08005340 case RIL_REQUEST_SET_UICC_SUBSCRIPTION: return "SET_UICC_SUBSCRIPTION";
5341 case RIL_REQUEST_ALLOW_DATA: return "ALLOW_DATA";
5342 case RIL_REQUEST_GET_HARDWARE_CONFIG: return "GET_HARDWARE_CONFIG";
5343 case RIL_REQUEST_SIM_AUTHENTICATION: return "SIM_AUTHENTICATION";
5344 case RIL_REQUEST_GET_DC_RT_INFO: return "GET_DC_RT_INFO";
5345 case RIL_REQUEST_SET_DC_RT_INFO_RATE: return "SET_DC_RT_INFO_RATE";
5346 case RIL_REQUEST_SET_DATA_PROFILE: return "SET_DATA_PROFILE";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005347 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
5348 case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
5349 case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
5350 case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
5351 case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
5352 case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
5353 case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
5354 case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
5355 case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
5356 case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
Howard Subd82ef12015-04-12 10:25:05 +02005357 case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
5358 case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005359 case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
5360 case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
5361 case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
5362 case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
5363 case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FUL";
5364 case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005365 case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
5366 case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
5367 case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_NEW_CDMA_SMS";
5368 case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_NEW_BROADCAST_SMS";
5369 case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
5370 case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
5371 case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
5372 case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
5373 case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
5374 case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
5375 case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
5376 case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONE";
5377 case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
5378 case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED";
5379 case RIL_UNSOL_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
5380 case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
5381 case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
5382 case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED";
Ethan Chend6e30652013-08-04 22:49:56 -07005383 case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST";
Andrew Jiangca4a9a02014-01-18 18:04:08 -05005384 case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return "RESPONSE_IMS_NETWORK_STATE_CHANGED";
Howard Sue32dbfd2015-01-07 15:55:57 +08005385 case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED: return "UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED";
5386 case RIL_UNSOL_SRVCC_STATE_NOTIFY: return "UNSOL_SRVCC_STATE_NOTIFY";
5387 case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: return "HARDWARE_CONFIG_CHANGED";
5388 case RIL_UNSOL_DC_RT_INFO_CHANGED: return "UNSOL_DC_RT_INFO_CHANGED";
Howard Subd82ef12015-04-12 10:25:05 +02005389 case RIL_UNSOL_RADIO_CAPABILITY: return "UNSOL_RADIO_CAPABILITY";
5390 case RIL_UNSOL_ON_SS: return "UNSOL_ON_SS";
5391 case RIL_UNSOL_STK_CC_ALPHA_NOTIFY: return "UNSOL_STK_CC_ALPHA_NOTIFY";
Howard Sue32dbfd2015-01-07 15:55:57 +08005392 case RIL_REQUEST_SHUTDOWN: return "SHUTDOWN";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005393 default: return "<unknown request>";
5394 }
5395}
5396
Howard Sue32dbfd2015-01-07 15:55:57 +08005397const char *
5398rilSocketIdToString(RIL_SOCKET_ID socket_id)
5399{
5400 switch(socket_id) {
5401 case RIL_SOCKET_1:
5402 return "RIL_SOCKET_1";
5403#if (SIM_COUNT >= 2)
5404 case RIL_SOCKET_2:
5405 return "RIL_SOCKET_2";
5406#endif
5407#if (SIM_COUNT >= 3)
5408 case RIL_SOCKET_3:
5409 return "RIL_SOCKET_3";
5410#endif
5411#if (SIM_COUNT >= 4)
5412 case RIL_SOCKET_4:
5413 return "RIL_SOCKET_4";
5414#endif
5415 default:
5416 return "not a valid RIL";
5417 }
5418}
5419
Sanket Padawe9343e872016-01-11 12:45:43 -08005420/*
5421 * Returns true for a debuggable build.
5422 */
5423static bool isDebuggable() {
5424 char debuggable[PROP_VALUE_MAX];
5425 property_get("ro.debuggable", debuggable, "0");
5426 if (strcmp(debuggable, "1") == 0) {
5427 return true;
5428 }
5429 return false;
5430}
5431
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005432} /* namespace android */
Dheeraj Shettycc231012014-07-02 21:27:57 +02005433
5434void rilEventAddWakeup_helper(struct ril_event *ev) {
5435 android::rilEventAddWakeup(ev);
5436}
5437
5438void listenCallback_helper(int fd, short flags, void *param) {
5439 android::listenCallback(fd, flags, param);
5440}
5441
5442int blockingWrite_helper(int fd, void *buffer, size_t len) {
5443 return android::blockingWrite(fd, buffer, len);
5444}