blob: beae8295656bb1d4cb245c779230e2b44674ea24 [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>
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020033#include <pwd.h>
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020034#include <stdio.h>
35#include <stdlib.h>
36#include <stdarg.h>
37#include <string.h>
38#include <unistd.h>
39#include <fcntl.h>
40#include <time.h>
41#include <errno.h>
42#include <assert.h>
43#include <ctype.h>
44#include <alloca.h>
45#include <sys/un.h>
46#include <assert.h>
47#include <netinet/in.h>
48#include <cutils/properties.h>
Dheeraj Shettycc231012014-07-02 21:27:57 +020049#include <RilSapSocket.h>
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020050
Dheeraj Shettycc231012014-07-02 21:27:57 +020051extern "C" void
52RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020053namespace android {
54
55#define PHONE_PROCESS "radio"
Dheeraj Shettycc231012014-07-02 21:27:57 +020056#define BLUETOOTH_PROCESS "bluetooth"
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020057
58#define SOCKET_NAME_RIL "rild"
Howard Sue32dbfd2015-01-07 15:55:57 +080059#define SOCKET2_NAME_RIL "rild2"
60#define SOCKET3_NAME_RIL "rild3"
61#define SOCKET4_NAME_RIL "rild4"
62
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020063#define SOCKET_NAME_RIL_DEBUG "rild-debug"
64
65#define ANDROID_WAKE_LOCK_NAME "radio-interface"
66
Nathan Haroldd6306fa2015-07-28 14:54:58 -070067#define ANDROID_WAKE_LOCK_SECS 0
68#define ANDROID_WAKE_LOCK_USECS 200000
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020069
70#define PROPERTY_RIL_IMPL "gsm.version.ril-impl"
Christopher N. Hesseb8400a22015-12-12 11:49:42 +010071#define PROPERTY_QAN_ELEMENTS "ro.ril.telephony.mqanelements"
Daniel Hillenbrand601dc852013-07-07 10:06:59 +020072
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
113 #define appendPrintBuf(x...) sprintf(printBuf, x)
114#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);
Utkarsh Guptaf7a63e52015-05-10 16:53:37 +0530281static int responseStringsNetworks(Parcel &p, void *response, size_t responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200282static int responseStrings(Parcel &p, void *response, size_t responselen, bool network_search);
283static int responseString(Parcel &p, void *response, size_t responselen);
284static int responseVoid(Parcel &p, void *response, size_t responselen);
285static int responseCallList(Parcel &p, void *response, size_t responselen);
286static int responseSMS(Parcel &p, void *response, size_t responselen);
287static int responseSIM_IO(Parcel &p, void *response, size_t responselen);
288static int responseCallForwards(Parcel &p, void *response, size_t responselen);
289static int responseDataCallList(Parcel &p, void *response, size_t responselen);
290static int responseSetupDataCall(Parcel &p, void *response, size_t responselen);
291static int responseRaw(Parcel &p, void *response, size_t responselen);
292static int responseSsn(Parcel &p, void *response, size_t responselen);
293static int responseSimStatus(Parcel &p, void *response, size_t responselen);
294static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen);
295static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen);
296static int responseCdmaSms(Parcel &p, void *response, size_t responselen);
297static int responseCellList(Parcel &p, void *response, size_t responselen);
298static int responseCdmaInformationRecords(Parcel &p,void *response, size_t responselen);
299static int responseRilSignalStrength(Parcel &p,void *response, size_t responselen);
300static int responseCallRing(Parcel &p, void *response, size_t responselen);
301static int responseCdmaSignalInfoRecord(Parcel &p,void *response, size_t responselen);
302static int responseCdmaCallWaiting(Parcel &p,void *response, size_t responselen);
303static int responseSimRefresh(Parcel &p, void *response, size_t responselen);
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200304static int responseCellInfoList(Parcel &p, void *response, size_t responselen);
Howard Sue32dbfd2015-01-07 15:55:57 +0800305static int responseHardwareConfig(Parcel &p, void *response, size_t responselen);
306static int responseDcRtInfo(Parcel &p, void *response, size_t responselen);
Howard Subd82ef12015-04-12 10:25:05 +0200307static int responseRadioCapability(Parcel &p, void *response, size_t responselen);
308static int responseSSData(Parcel &p, void *response, size_t responselen);
fenglu9bdede02015-04-14 14:53:55 -0700309static int responseLceStatus(Parcel &p, void *response, size_t responselen);
310static int responseLceData(Parcel &p, void *response, size_t responselen);
Prerepa Viswanadham8e755592015-05-28 00:37:32 -0700311static int responseActivityData(Parcel &p, void *response, size_t responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200312
313static int decodeVoiceRadioTechnology (RIL_RadioState radioState);
314static int decodeCdmaSubscriptionSource (RIL_RadioState radioState);
Howard Subd82ef12015-04-12 10:25:05 +0200315static RIL_RadioState processRadioState(RIL_RadioState newRadioState);
316
317static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200318
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
Howard Subd82ef12015-04-12 10:25:05 +0200348static CommandInfo s_commands_v[] = {
349#include "ril_commands_vendor.h"
350};
351
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200352static UnsolResponseInfo s_unsolResponses[] = {
353#include "ril_unsol_commands.h"
354};
355
Howard Subd82ef12015-04-12 10:25:05 +0200356static UnsolResponseInfo s_unsolResponses_v[] = {
357#include "ril_unsol_commands_vendor.h"
358};
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;
Sayd1052772015-12-13 17:25:01 +0900792#if defined(MODEM_TYPE_XMM7260) || defined(MODEM_TYPE_M7450) || defined(MODEM_TYPE_SS333)
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
Sayd1052772015-12-13 17:25:01 +0900809#if defined(MODEM_TYPE_XMM7260) || defined(MODEM_TYPE_M7450) || defined(MODEM_TYPE_SS333)
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) {
Sayd1052772015-12-13 17:25:01 +0900839#if defined(MODEM_TYPE_XMM6262) || defined(MODEM_TYPE_XMM7260) \
840 || defined(MODEM_TYPE_M7450) || defined(MODEM_TYPE_SS333)
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200841 dial.uusInfo = NULL;
Andreas Schneiderf68609b2015-04-07 19:01:34 +0200842#elif defined(MODEM_TYPE_XMM6260)
Howard Sue32dbfd2015-01-07 15:55:57 +0800843 /* Samsung hack */
844 memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
845 uusInfo.uusType = (RIL_UUS_Type) 0;
846 uusInfo.uusDcs = (RIL_UUS_DCS) 0;
847 uusInfo.uusData = NULL;
848 uusInfo.uusLength = 0;
849 dial.uusInfo = &uusInfo;
850#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200851 } else {
852 int32_t len;
853
854 memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
855
856 status = p.readInt32(&t);
857 uusInfo.uusType = (RIL_UUS_Type) t;
858
859 status = p.readInt32(&t);
860 uusInfo.uusDcs = (RIL_UUS_DCS) t;
861
862 status = p.readInt32(&len);
863 if (status != NO_ERROR) {
864 goto invalid;
865 }
866
867 // The java code writes -1 for null arrays
868 if (((int) len) == -1) {
869 uusInfo.uusData = NULL;
870 len = 0;
871 } else {
872 uusInfo.uusData = (char*) p.readInplace(len);
873 }
874
875 uusInfo.uusLength = len;
876 dial.uusInfo = &uusInfo;
877 }
878 sizeOfDial = sizeof(dial);
879 }
880
881 startRequest;
882 appendPrintBuf("%snum=%s,clir=%d", printBuf, dial.address, dial.clir);
883 if (uusPresent) {
884 appendPrintBuf("%s,uusType=%d,uusDcs=%d,uusLen=%d", printBuf,
885 dial.uusInfo->uusType, dial.uusInfo->uusDcs,
886 dial.uusInfo->uusLength);
887 }
888 closeRequest;
889 printRequest(pRI->token, pRI->pCI->requestNumber);
890
Howard Sue32dbfd2015-01-07 15:55:57 +0800891 CALL_ONREQUEST(pRI->pCI->requestNumber, &dial, sizeOfDial, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200892
893#ifdef MEMSET_FREED
894 memsetString (dial.address);
895#endif
896
897 free (dial.address);
898
899#ifdef MEMSET_FREED
900 memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
901 memset(&dial, 0, sizeof(dial));
902#endif
903
904 return;
905invalid:
906 invalidCommandBlock(pRI);
907 return;
908}
909
910/**
911 * Callee expects const RIL_SIM_IO *
912 * Payload is:
913 * int32_t command
914 * int32_t fileid
915 * String path
916 * int32_t p1, p2, p3
917 * String data
918 * String pin2
919 * String aidPtr
920 */
921static void
922dispatchSIM_IO (Parcel &p, RequestInfo *pRI) {
923 union RIL_SIM_IO {
924 RIL_SIM_IO_v6 v6;
925 RIL_SIM_IO_v5 v5;
926 } simIO;
927
928 int32_t t;
929 int size;
930 status_t status;
931
Robert Greenwaltbc29c432015-04-29 16:57:39 -0700932#if VDBG
Mark Salyzyn961fd022015-04-09 07:18:35 -0700933 RLOGD("dispatchSIM_IO");
Robert Greenwaltbc29c432015-04-29 16:57:39 -0700934#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200935 memset (&simIO, 0, sizeof(simIO));
936
937 // note we only check status at the end
938
939 status = p.readInt32(&t);
940 simIO.v6.command = (int)t;
941
942 status = p.readInt32(&t);
943 simIO.v6.fileid = (int)t;
944
945 simIO.v6.path = strdupReadString(p);
946
947 status = p.readInt32(&t);
948 simIO.v6.p1 = (int)t;
949
950 status = p.readInt32(&t);
951 simIO.v6.p2 = (int)t;
952
953 status = p.readInt32(&t);
954 simIO.v6.p3 = (int)t;
955
956 simIO.v6.data = strdupReadString(p);
957 simIO.v6.pin2 = strdupReadString(p);
958 simIO.v6.aidPtr = strdupReadString(p);
959
960 startRequest;
961 appendPrintBuf("%scmd=0x%X,efid=0x%X,path=%s,%d,%d,%d,%s,pin2=%s,aid=%s", printBuf,
962 simIO.v6.command, simIO.v6.fileid, (char*)simIO.v6.path,
963 simIO.v6.p1, simIO.v6.p2, simIO.v6.p3,
964 (char*)simIO.v6.data, (char*)simIO.v6.pin2, simIO.v6.aidPtr);
965 closeRequest;
966 printRequest(pRI->token, pRI->pCI->requestNumber);
967
968 if (status != NO_ERROR) {
969 goto invalid;
970 }
971
972 size = (s_callbacks.version < 6) ? sizeof(simIO.v5) : sizeof(simIO.v6);
Howard Sue32dbfd2015-01-07 15:55:57 +0800973 CALL_ONREQUEST(pRI->pCI->requestNumber, &simIO, size, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200974
975#ifdef MEMSET_FREED
976 memsetString (simIO.v6.path);
977 memsetString (simIO.v6.data);
978 memsetString (simIO.v6.pin2);
979 memsetString (simIO.v6.aidPtr);
980#endif
981
982 free (simIO.v6.path);
983 free (simIO.v6.data);
984 free (simIO.v6.pin2);
985 free (simIO.v6.aidPtr);
986
987#ifdef MEMSET_FREED
988 memset(&simIO, 0, sizeof(simIO));
989#endif
990
991 return;
992invalid:
993 invalidCommandBlock(pRI);
994 return;
995}
996
997/**
Howard Sue32dbfd2015-01-07 15:55:57 +0800998 * Callee expects const RIL_SIM_APDU *
999 * Payload is:
1000 * int32_t sessionid
1001 * int32_t cla
1002 * int32_t instruction
1003 * int32_t p1, p2, p3
1004 * String data
1005 */
1006static void
1007dispatchSIM_APDU (Parcel &p, RequestInfo *pRI) {
1008 int32_t t;
1009 status_t status;
1010 RIL_SIM_APDU apdu;
1011
Robert Greenwaltbc29c432015-04-29 16:57:39 -07001012#if VDBG
Mark Salyzyn961fd022015-04-09 07:18:35 -07001013 RLOGD("dispatchSIM_APDU");
Robert Greenwaltbc29c432015-04-29 16:57:39 -07001014#endif
Howard Sue32dbfd2015-01-07 15:55:57 +08001015 memset (&apdu, 0, sizeof(RIL_SIM_APDU));
1016
1017 // Note we only check status at the end. Any single failure leads to
1018 // subsequent reads filing.
1019 status = p.readInt32(&t);
1020 apdu.sessionid = (int)t;
1021
1022 status = p.readInt32(&t);
1023 apdu.cla = (int)t;
1024
1025 status = p.readInt32(&t);
1026 apdu.instruction = (int)t;
1027
1028 status = p.readInt32(&t);
1029 apdu.p1 = (int)t;
1030
1031 status = p.readInt32(&t);
1032 apdu.p2 = (int)t;
1033
1034 status = p.readInt32(&t);
1035 apdu.p3 = (int)t;
1036
1037 apdu.data = strdupReadString(p);
1038
1039 startRequest;
1040 appendPrintBuf("%ssessionid=%d,cla=%d,ins=%d,p1=%d,p2=%d,p3=%d,data=%s",
1041 printBuf, apdu.sessionid, apdu.cla, apdu.instruction, apdu.p1, apdu.p2,
1042 apdu.p3, (char*)apdu.data);
1043 closeRequest;
1044 printRequest(pRI->token, pRI->pCI->requestNumber);
1045
1046 if (status != NO_ERROR) {
1047 goto invalid;
1048 }
1049
1050 CALL_ONREQUEST(pRI->pCI->requestNumber, &apdu, sizeof(RIL_SIM_APDU), pRI, pRI->socket_id);
1051
1052#ifdef MEMSET_FREED
1053 memsetString(apdu.data);
1054#endif
1055 free(apdu.data);
1056
1057#ifdef MEMSET_FREED
1058 memset(&apdu, 0, sizeof(RIL_SIM_APDU));
1059#endif
1060
1061 return;
1062invalid:
1063 invalidCommandBlock(pRI);
1064 return;
1065}
1066
Howard Subd82ef12015-04-12 10:25:05 +02001067
Howard Sue32dbfd2015-01-07 15:55:57 +08001068/**
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001069 * Callee expects const RIL_CallForwardInfo *
1070 * Payload is:
1071 * int32_t status/action
1072 * int32_t reason
1073 * int32_t serviceCode
1074 * int32_t toa
1075 * String number (0 length -> null)
1076 * int32_t timeSeconds
1077 */
1078static void
1079dispatchCallForward(Parcel &p, RequestInfo *pRI) {
1080 RIL_CallForwardInfo cff;
1081 int32_t t;
1082 status_t status;
1083
Mark Salyzyn961fd022015-04-09 07:18:35 -07001084 RLOGD("dispatchCallForward");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001085 memset (&cff, 0, sizeof(cff));
1086
1087 // note we only check status at the end
1088
1089 status = p.readInt32(&t);
1090 cff.status = (int)t;
1091
1092 status = p.readInt32(&t);
1093 cff.reason = (int)t;
1094
1095 status = p.readInt32(&t);
1096 cff.serviceClass = (int)t;
1097
1098 status = p.readInt32(&t);
1099 cff.toa = (int)t;
1100
1101 cff.number = strdupReadString(p);
1102
1103 status = p.readInt32(&t);
1104 cff.timeSeconds = (int)t;
1105
1106 if (status != NO_ERROR) {
1107 goto invalid;
1108 }
1109
1110 // special case: number 0-length fields is null
1111
1112 if (cff.number != NULL && strlen (cff.number) == 0) {
1113 cff.number = NULL;
1114 }
1115
1116 startRequest;
1117 appendPrintBuf("%sstat=%d,reason=%d,serv=%d,toa=%d,%s,tout=%d", printBuf,
1118 cff.status, cff.reason, cff.serviceClass, cff.toa,
1119 (char*)cff.number, cff.timeSeconds);
1120 closeRequest;
1121 printRequest(pRI->token, pRI->pCI->requestNumber);
1122
Howard Sue32dbfd2015-01-07 15:55:57 +08001123 CALL_ONREQUEST(pRI->pCI->requestNumber, &cff, sizeof(cff), pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001124
1125#ifdef MEMSET_FREED
1126 memsetString(cff.number);
1127#endif
1128
1129 free (cff.number);
1130
1131#ifdef MEMSET_FREED
1132 memset(&cff, 0, sizeof(cff));
1133#endif
1134
1135 return;
1136invalid:
1137 invalidCommandBlock(pRI);
1138 return;
1139}
1140
1141
1142static void
1143dispatchRaw(Parcel &p, RequestInfo *pRI) {
1144 int32_t len;
1145 status_t status;
1146 const void *data;
1147
1148 status = p.readInt32(&len);
1149
1150 if (status != NO_ERROR) {
1151 goto invalid;
1152 }
1153
1154 // The java code writes -1 for null arrays
1155 if (((int)len) == -1) {
1156 data = NULL;
1157 len = 0;
1158 }
1159
1160 data = p.readInplace(len);
1161
1162 startRequest;
1163 appendPrintBuf("%sraw_size=%d", printBuf, len);
1164 closeRequest;
1165 printRequest(pRI->token, pRI->pCI->requestNumber);
1166
Howard Sue32dbfd2015-01-07 15:55:57 +08001167 CALL_ONREQUEST(pRI->pCI->requestNumber, const_cast<void *>(data), len, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001168
1169 return;
1170invalid:
1171 invalidCommandBlock(pRI);
1172 return;
1173}
1174
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001175static status_t
1176constructCdmaSms(Parcel &p, RequestInfo *pRI, RIL_CDMA_SMS_Message& rcsm) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001177 int32_t t;
1178 uint8_t ut;
1179 status_t status;
1180 int32_t digitCount;
1181 int digitLimit;
1182
1183 memset(&rcsm, 0, sizeof(rcsm));
1184
1185 status = p.readInt32(&t);
1186 rcsm.uTeleserviceID = (int) t;
1187
1188 status = p.read(&ut,sizeof(ut));
1189 rcsm.bIsServicePresent = (uint8_t) ut;
1190
1191 status = p.readInt32(&t);
1192 rcsm.uServicecategory = (int) t;
1193
1194 status = p.readInt32(&t);
1195 rcsm.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
1196
1197 status = p.readInt32(&t);
1198 rcsm.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
1199
1200 status = p.readInt32(&t);
1201 rcsm.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
1202
1203 status = p.readInt32(&t);
1204 rcsm.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
1205
1206 status = p.read(&ut,sizeof(ut));
1207 rcsm.sAddress.number_of_digits= (uint8_t) ut;
1208
1209 digitLimit= MIN((rcsm.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
1210 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1211 status = p.read(&ut,sizeof(ut));
1212 rcsm.sAddress.digits[digitCount] = (uint8_t) ut;
1213 }
1214
1215 status = p.readInt32(&t);
1216 rcsm.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
1217
1218 status = p.read(&ut,sizeof(ut));
1219 rcsm.sSubAddress.odd = (uint8_t) ut;
1220
1221 status = p.read(&ut,sizeof(ut));
1222 rcsm.sSubAddress.number_of_digits = (uint8_t) ut;
1223
1224 digitLimit= MIN((rcsm.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
1225 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1226 status = p.read(&ut,sizeof(ut));
1227 rcsm.sSubAddress.digits[digitCount] = (uint8_t) ut;
1228 }
1229
1230 status = p.readInt32(&t);
1231 rcsm.uBearerDataLen = (int) t;
1232
1233 digitLimit= MIN((rcsm.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
1234 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1235 status = p.read(&ut, sizeof(ut));
1236 rcsm.aBearerData[digitCount] = (uint8_t) ut;
1237 }
1238
1239 if (status != NO_ERROR) {
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001240 return status;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001241 }
1242
1243 startRequest;
1244 appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
1245 sAddress.digit_mode=%d, sAddress.Number_mode=%d, sAddress.number_type=%d, ",
1246 printBuf, rcsm.uTeleserviceID,rcsm.bIsServicePresent,rcsm.uServicecategory,
1247 rcsm.sAddress.digit_mode, rcsm.sAddress.number_mode,rcsm.sAddress.number_type);
1248 closeRequest;
1249
1250 printRequest(pRI->token, pRI->pCI->requestNumber);
1251
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001252 return status;
1253}
1254
1255static void
1256dispatchCdmaSms(Parcel &p, RequestInfo *pRI) {
1257 RIL_CDMA_SMS_Message rcsm;
1258
Mark Salyzyn961fd022015-04-09 07:18:35 -07001259 RLOGD("dispatchCdmaSms");
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001260 if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) {
1261 goto invalid;
1262 }
1263
Howard Sue32dbfd2015-01-07 15:55:57 +08001264 CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm),pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001265
1266#ifdef MEMSET_FREED
1267 memset(&rcsm, 0, sizeof(rcsm));
1268#endif
1269
1270 return;
1271
1272invalid:
1273 invalidCommandBlock(pRI);
1274 return;
1275}
1276
1277static void
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001278dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) {
1279 RIL_IMS_SMS_Message rism;
1280 RIL_CDMA_SMS_Message rcsm;
1281
Mark Salyzyn961fd022015-04-09 07:18:35 -07001282 RLOGD("dispatchImsCdmaSms: retry=%d, messageRef=%d", retry, messageRef);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001283
1284 if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) {
1285 goto invalid;
1286 }
1287 memset(&rism, 0, sizeof(rism));
1288 rism.tech = RADIO_TECH_3GPP2;
1289 rism.retry = retry;
1290 rism.messageRef = messageRef;
1291 rism.message.cdmaMessage = &rcsm;
1292
Howard Sue32dbfd2015-01-07 15:55:57 +08001293 CALL_ONREQUEST(pRI->pCI->requestNumber, &rism,
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001294 sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t)
Howard Sue32dbfd2015-01-07 15:55:57 +08001295 +sizeof(rcsm),pRI, pRI->socket_id);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001296
1297#ifdef MEMSET_FREED
1298 memset(&rcsm, 0, sizeof(rcsm));
1299 memset(&rism, 0, sizeof(rism));
1300#endif
1301
1302 return;
1303
1304invalid:
1305 invalidCommandBlock(pRI);
1306 return;
1307}
1308
1309static void
1310dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) {
1311 RIL_IMS_SMS_Message rism;
1312 int32_t countStrings;
1313 status_t status;
1314 size_t datalen;
1315 char **pStrings;
Mark Salyzyn961fd022015-04-09 07:18:35 -07001316 RLOGD("dispatchImsGsmSms: retry=%d, messageRef=%d", retry, messageRef);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001317
1318 status = p.readInt32 (&countStrings);
1319
1320 if (status != NO_ERROR) {
1321 goto invalid;
1322 }
1323
1324 memset(&rism, 0, sizeof(rism));
1325 rism.tech = RADIO_TECH_3GPP;
1326 rism.retry = retry;
1327 rism.messageRef = messageRef;
1328
1329 startRequest;
Howard Sue32dbfd2015-01-07 15:55:57 +08001330 appendPrintBuf("%stech=%d, retry=%d, messageRef=%d, ", printBuf,
1331 (int)rism.tech, (int)rism.retry, rism.messageRef);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001332 if (countStrings == 0) {
1333 // just some non-null pointer
1334 pStrings = (char **)alloca(sizeof(char *));
1335 datalen = 0;
1336 } else if (((int)countStrings) == -1) {
1337 pStrings = NULL;
1338 datalen = 0;
1339 } else {
1340 datalen = sizeof(char *) * countStrings;
1341
1342 pStrings = (char **)alloca(datalen);
1343
1344 for (int i = 0 ; i < countStrings ; i++) {
1345 pStrings[i] = strdupReadString(p);
1346 appendPrintBuf("%s%s,", printBuf, pStrings[i]);
1347 }
1348 }
1349 removeLastChar;
1350 closeRequest;
1351 printRequest(pRI->token, pRI->pCI->requestNumber);
1352
1353 rism.message.gsmMessage = pStrings;
Howard Sue32dbfd2015-01-07 15:55:57 +08001354 CALL_ONREQUEST(pRI->pCI->requestNumber, &rism,
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001355 sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t)
Howard Sue32dbfd2015-01-07 15:55:57 +08001356 +datalen, pRI, pRI->socket_id);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001357
1358 if (pStrings != NULL) {
1359 for (int i = 0 ; i < countStrings ; i++) {
1360#ifdef MEMSET_FREED
1361 memsetString (pStrings[i]);
1362#endif
1363 free(pStrings[i]);
1364 }
1365
1366#ifdef MEMSET_FREED
1367 memset(pStrings, 0, datalen);
1368#endif
1369 }
1370
1371#ifdef MEMSET_FREED
1372 memset(&rism, 0, sizeof(rism));
1373#endif
1374 return;
1375invalid:
1376 ALOGE("dispatchImsGsmSms invalid block");
1377 invalidCommandBlock(pRI);
1378 return;
1379}
1380
1381static void
1382dispatchImsSms(Parcel &p, RequestInfo *pRI) {
1383 int32_t t;
1384 status_t status = p.readInt32(&t);
1385 RIL_RadioTechnologyFamily format;
1386 uint8_t retry;
1387 int32_t messageRef;
1388
Mark Salyzyn961fd022015-04-09 07:18:35 -07001389 RLOGD("dispatchImsSms");
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001390 if (status != NO_ERROR) {
1391 goto invalid;
1392 }
1393 format = (RIL_RadioTechnologyFamily) t;
1394
1395 // read retry field
1396 status = p.read(&retry,sizeof(retry));
1397 if (status != NO_ERROR) {
1398 goto invalid;
1399 }
1400 // read messageRef field
1401 status = p.read(&messageRef,sizeof(messageRef));
1402 if (status != NO_ERROR) {
1403 goto invalid;
1404 }
1405
1406 if (RADIO_TECH_3GPP == format) {
1407 dispatchImsGsmSms(p, pRI, retry, messageRef);
1408 } else if (RADIO_TECH_3GPP2 == format) {
1409 dispatchImsCdmaSms(p, pRI, retry, messageRef);
1410 } else {
1411 ALOGE("requestImsSendSMS invalid format value =%d", format);
1412 }
1413
1414 return;
1415
1416invalid:
1417 invalidCommandBlock(pRI);
1418 return;
1419}
1420
1421static void
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001422dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI) {
1423 RIL_CDMA_SMS_Ack rcsa;
1424 int32_t t;
1425 status_t status;
1426 int32_t digitCount;
1427
Mark Salyzyn961fd022015-04-09 07:18:35 -07001428 RLOGD("dispatchCdmaSmsAck");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001429 memset(&rcsa, 0, sizeof(rcsa));
1430
1431 status = p.readInt32(&t);
1432 rcsa.uErrorClass = (RIL_CDMA_SMS_ErrorClass) t;
1433
1434 status = p.readInt32(&t);
1435 rcsa.uSMSCauseCode = (int) t;
1436
1437 if (status != NO_ERROR) {
1438 goto invalid;
1439 }
1440
1441 startRequest;
1442 appendPrintBuf("%suErrorClass=%d, uTLStatus=%d, ",
1443 printBuf, rcsa.uErrorClass, rcsa.uSMSCauseCode);
1444 closeRequest;
1445
1446 printRequest(pRI->token, pRI->pCI->requestNumber);
1447
Howard Sue32dbfd2015-01-07 15:55:57 +08001448 CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa),pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001449
1450#ifdef MEMSET_FREED
1451 memset(&rcsa, 0, sizeof(rcsa));
1452#endif
1453
1454 return;
1455
1456invalid:
1457 invalidCommandBlock(pRI);
1458 return;
1459}
1460
1461static void
1462dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI) {
1463 int32_t t;
1464 status_t status;
1465 int32_t num;
1466
1467 status = p.readInt32(&num);
1468 if (status != NO_ERROR) {
1469 goto invalid;
1470 }
1471
Ethan Chend6e30652013-08-04 22:49:56 -07001472 {
1473 RIL_GSM_BroadcastSmsConfigInfo gsmBci[num];
1474 RIL_GSM_BroadcastSmsConfigInfo *gsmBciPtrs[num];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001475
Ethan Chend6e30652013-08-04 22:49:56 -07001476 startRequest;
1477 for (int i = 0 ; i < num ; i++ ) {
1478 gsmBciPtrs[i] = &gsmBci[i];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001479
Ethan Chend6e30652013-08-04 22:49:56 -07001480 status = p.readInt32(&t);
1481 gsmBci[i].fromServiceId = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001482
Ethan Chend6e30652013-08-04 22:49:56 -07001483 status = p.readInt32(&t);
1484 gsmBci[i].toServiceId = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001485
Ethan Chend6e30652013-08-04 22:49:56 -07001486 status = p.readInt32(&t);
1487 gsmBci[i].fromCodeScheme = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001488
Ethan Chend6e30652013-08-04 22:49:56 -07001489 status = p.readInt32(&t);
1490 gsmBci[i].toCodeScheme = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001491
Ethan Chend6e30652013-08-04 22:49:56 -07001492 status = p.readInt32(&t);
1493 gsmBci[i].selected = (uint8_t) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001494
Ethan Chend6e30652013-08-04 22:49:56 -07001495 appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId =%d, \
1496 fromCodeScheme=%d, toCodeScheme=%d, selected =%d]", printBuf, i,
1497 gsmBci[i].fromServiceId, gsmBci[i].toServiceId,
1498 gsmBci[i].fromCodeScheme, gsmBci[i].toCodeScheme,
1499 gsmBci[i].selected);
1500 }
1501 closeRequest;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001502
Ethan Chend6e30652013-08-04 22:49:56 -07001503 if (status != NO_ERROR) {
1504 goto invalid;
1505 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001506
Howard Sue32dbfd2015-01-07 15:55:57 +08001507 CALL_ONREQUEST(pRI->pCI->requestNumber,
Ethan Chend6e30652013-08-04 22:49:56 -07001508 gsmBciPtrs,
1509 num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *),
Howard Sue32dbfd2015-01-07 15:55:57 +08001510 pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001511
1512#ifdef MEMSET_FREED
Ethan Chend6e30652013-08-04 22:49:56 -07001513 memset(gsmBci, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo));
1514 memset(gsmBciPtrs, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001515#endif
Ethan Chend6e30652013-08-04 22:49:56 -07001516 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001517
1518 return;
1519
1520invalid:
1521 invalidCommandBlock(pRI);
1522 return;
1523}
1524
1525static void
1526dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI) {
1527 int32_t t;
1528 status_t status;
1529 int32_t num;
1530
1531 status = p.readInt32(&num);
1532 if (status != NO_ERROR) {
1533 goto invalid;
1534 }
1535
Ethan Chend6e30652013-08-04 22:49:56 -07001536 {
1537 RIL_CDMA_BroadcastSmsConfigInfo cdmaBci[num];
1538 RIL_CDMA_BroadcastSmsConfigInfo *cdmaBciPtrs[num];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001539
Ethan Chend6e30652013-08-04 22:49:56 -07001540 startRequest;
1541 for (int i = 0 ; i < num ; i++ ) {
1542 cdmaBciPtrs[i] = &cdmaBci[i];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001543
Ethan Chend6e30652013-08-04 22:49:56 -07001544 status = p.readInt32(&t);
1545 cdmaBci[i].service_category = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001546
Ethan Chend6e30652013-08-04 22:49:56 -07001547 status = p.readInt32(&t);
1548 cdmaBci[i].language = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001549
Ethan Chend6e30652013-08-04 22:49:56 -07001550 status = p.readInt32(&t);
1551 cdmaBci[i].selected = (uint8_t) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001552
Ethan Chend6e30652013-08-04 22:49:56 -07001553 appendPrintBuf("%s [%d: service_category=%d, language =%d, \
1554 entries.bSelected =%d]", printBuf, i, cdmaBci[i].service_category,
1555 cdmaBci[i].language, cdmaBci[i].selected);
1556 }
1557 closeRequest;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001558
Ethan Chend6e30652013-08-04 22:49:56 -07001559 if (status != NO_ERROR) {
1560 goto invalid;
1561 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001562
Howard Sue32dbfd2015-01-07 15:55:57 +08001563 CALL_ONREQUEST(pRI->pCI->requestNumber,
Ethan Chend6e30652013-08-04 22:49:56 -07001564 cdmaBciPtrs,
1565 num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *),
Howard Sue32dbfd2015-01-07 15:55:57 +08001566 pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001567
1568#ifdef MEMSET_FREED
Ethan Chend6e30652013-08-04 22:49:56 -07001569 memset(cdmaBci, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo));
1570 memset(cdmaBciPtrs, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001571#endif
Ethan Chend6e30652013-08-04 22:49:56 -07001572 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001573
1574 return;
1575
1576invalid:
1577 invalidCommandBlock(pRI);
1578 return;
1579}
1580
1581static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI) {
1582 RIL_CDMA_SMS_WriteArgs rcsw;
1583 int32_t t;
1584 uint32_t ut;
1585 uint8_t uct;
1586 status_t status;
1587 int32_t digitCount;
1588
1589 memset(&rcsw, 0, sizeof(rcsw));
1590
1591 status = p.readInt32(&t);
1592 rcsw.status = t;
1593
1594 status = p.readInt32(&t);
1595 rcsw.message.uTeleserviceID = (int) t;
1596
1597 status = p.read(&uct,sizeof(uct));
1598 rcsw.message.bIsServicePresent = (uint8_t) uct;
1599
1600 status = p.readInt32(&t);
1601 rcsw.message.uServicecategory = (int) t;
1602
1603 status = p.readInt32(&t);
1604 rcsw.message.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
1605
1606 status = p.readInt32(&t);
1607 rcsw.message.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
1608
1609 status = p.readInt32(&t);
1610 rcsw.message.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
1611
1612 status = p.readInt32(&t);
1613 rcsw.message.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
1614
1615 status = p.read(&uct,sizeof(uct));
1616 rcsw.message.sAddress.number_of_digits = (uint8_t) uct;
1617
1618 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_ADDRESS_MAX; digitCount ++) {
1619 status = p.read(&uct,sizeof(uct));
1620 rcsw.message.sAddress.digits[digitCount] = (uint8_t) uct;
1621 }
1622
1623 status = p.readInt32(&t);
1624 rcsw.message.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
1625
1626 status = p.read(&uct,sizeof(uct));
1627 rcsw.message.sSubAddress.odd = (uint8_t) uct;
1628
1629 status = p.read(&uct,sizeof(uct));
1630 rcsw.message.sSubAddress.number_of_digits = (uint8_t) uct;
1631
1632 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_SUBADDRESS_MAX; digitCount ++) {
1633 status = p.read(&uct,sizeof(uct));
1634 rcsw.message.sSubAddress.digits[digitCount] = (uint8_t) uct;
1635 }
1636
1637 status = p.readInt32(&t);
1638 rcsw.message.uBearerDataLen = (int) t;
1639
1640 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_BEARER_DATA_MAX; digitCount ++) {
1641 status = p.read(&uct, sizeof(uct));
1642 rcsw.message.aBearerData[digitCount] = (uint8_t) uct;
1643 }
1644
1645 if (status != NO_ERROR) {
1646 goto invalid;
1647 }
1648
1649 startRequest;
1650 appendPrintBuf("%sstatus=%d, message.uTeleserviceID=%d, message.bIsServicePresent=%d, \
1651 message.uServicecategory=%d, message.sAddress.digit_mode=%d, \
1652 message.sAddress.number_mode=%d, \
1653 message.sAddress.number_type=%d, ",
1654 printBuf, rcsw.status, rcsw.message.uTeleserviceID, rcsw.message.bIsServicePresent,
1655 rcsw.message.uServicecategory, rcsw.message.sAddress.digit_mode,
1656 rcsw.message.sAddress.number_mode,
1657 rcsw.message.sAddress.number_type);
1658 closeRequest;
1659
1660 printRequest(pRI->token, pRI->pCI->requestNumber);
1661
Howard Sue32dbfd2015-01-07 15:55:57 +08001662 CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw),pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001663
1664#ifdef MEMSET_FREED
1665 memset(&rcsw, 0, sizeof(rcsw));
1666#endif
1667
1668 return;
1669
1670invalid:
1671 invalidCommandBlock(pRI);
1672 return;
1673
1674}
1675
Ethan Chend6e30652013-08-04 22:49:56 -07001676// For backwards compatibility in RIL_REQUEST_SETUP_DATA_CALL.
1677// Version 4 of the RIL interface adds a new PDP type parameter to support
1678// IPv6 and dual-stack PDP contexts. When dealing with a previous version of
1679// RIL, remove the parameter from the request.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001680static void dispatchDataCall(Parcel& p, RequestInfo *pRI) {
Ethan Chend6e30652013-08-04 22:49:56 -07001681 // In RIL v3, REQUEST_SETUP_DATA_CALL takes 6 parameters.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001682 const int numParamsRilV3 = 6;
1683
Ethan Chend6e30652013-08-04 22:49:56 -07001684 // The first bytes of the RIL parcel contain the request number and the
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001685 // serial number - see processCommandBuffer(). Copy them over too.
1686 int pos = p.dataPosition();
1687
1688 int numParams = p.readInt32();
1689 if (s_callbacks.version < 4 && numParams > numParamsRilV3) {
1690 Parcel p2;
1691 p2.appendFrom(&p, 0, pos);
1692 p2.writeInt32(numParamsRilV3);
1693 for(int i = 0; i < numParamsRilV3; i++) {
1694 p2.writeString16(p.readString16());
1695 }
1696 p2.setDataPosition(pos);
1697 dispatchStrings(p2, pRI);
1698 } else {
1699 p.setDataPosition(pos);
1700 dispatchStrings(p, pRI);
1701 }
1702}
1703
1704// For backwards compatibility with RILs that dont support RIL_REQUEST_VOICE_RADIO_TECH.
Ethan Chend6e30652013-08-04 22:49:56 -07001705// When all RILs handle this request, this function can be removed and
1706// the request can be sent directly to the RIL using dispatchVoid.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001707static void dispatchVoiceRadioTech(Parcel& p, RequestInfo *pRI) {
Howard Sue32dbfd2015-01-07 15:55:57 +08001708 RIL_RadioState state = CALL_ONSTATEREQUEST((RIL_SOCKET_ID)pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001709
1710 if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) {
1711 RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1712 }
1713
Ethan Chend6e30652013-08-04 22:49:56 -07001714 // RILs that support RADIO_STATE_ON should support this request.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001715 if (RADIO_STATE_ON == state) {
1716 dispatchVoid(p, pRI);
1717 return;
1718 }
1719
Ethan Chend6e30652013-08-04 22:49:56 -07001720 // For Older RILs, that do not support RADIO_STATE_ON, assume that they
1721 // will not support this new request either and decode Voice Radio Technology
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001722 // from Radio State
1723 voiceRadioTech = decodeVoiceRadioTechnology(state);
1724
1725 if (voiceRadioTech < 0)
1726 RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0);
1727 else
1728 RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &voiceRadioTech, sizeof(int));
1729}
1730
Ethan Chend6e30652013-08-04 22:49:56 -07001731// For backwards compatibility in RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:.
1732// When all RILs handle this request, this function can be removed and
1733// the request can be sent directly to the RIL using dispatchVoid.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001734static void dispatchCdmaSubscriptionSource(Parcel& p, RequestInfo *pRI) {
Howard Sue32dbfd2015-01-07 15:55:57 +08001735 RIL_RadioState state = CALL_ONSTATEREQUEST((RIL_SOCKET_ID)pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001736
1737 if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) {
1738 RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1739 }
1740
1741 // RILs that support RADIO_STATE_ON should support this request.
1742 if (RADIO_STATE_ON == state) {
1743 dispatchVoid(p, pRI);
1744 return;
1745 }
1746
Ethan Chend6e30652013-08-04 22:49:56 -07001747 // For Older RILs, that do not support RADIO_STATE_ON, assume that they
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001748 // will not support this new request either and decode CDMA Subscription Source
Ethan Chend6e30652013-08-04 22:49:56 -07001749 // from Radio State
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001750 cdmaSubscriptionSource = decodeCdmaSubscriptionSource(state);
1751
1752 if (cdmaSubscriptionSource < 0)
1753 RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0);
1754 else
1755 RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &cdmaSubscriptionSource, sizeof(int));
1756}
1757
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001758static void dispatchSetInitialAttachApn(Parcel &p, RequestInfo *pRI)
1759{
1760 RIL_InitialAttachApn pf;
1761 int32_t t;
1762 status_t status;
1763
1764 memset(&pf, 0, sizeof(pf));
1765
1766 pf.apn = strdupReadString(p);
1767 pf.protocol = strdupReadString(p);
1768
1769 status = p.readInt32(&t);
1770 pf.authtype = (int) t;
1771
1772 pf.username = strdupReadString(p);
1773 pf.password = strdupReadString(p);
1774
1775 startRequest;
1776 appendPrintBuf("%sapn=%s, protocol=%s, auth_type=%d, username=%s, password=%s",
Andreas Schneidera8d09502015-06-23 18:41:38 +02001777 printBuf, pf.apn, pf.protocol, pf.authtype, pf.username, pf.password);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001778 closeRequest;
1779 printRequest(pRI->token, pRI->pCI->requestNumber);
1780
1781 if (status != NO_ERROR) {
1782 goto invalid;
1783 }
Howard Sue32dbfd2015-01-07 15:55:57 +08001784 CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, pRI->socket_id);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001785
1786#ifdef MEMSET_FREED
1787 memsetString(pf.apn);
1788 memsetString(pf.protocol);
1789 memsetString(pf.username);
1790 memsetString(pf.password);
1791#endif
1792
1793 free(pf.apn);
1794 free(pf.protocol);
1795 free(pf.username);
1796 free(pf.password);
1797
1798#ifdef MEMSET_FREED
1799 memset(&pf, 0, sizeof(pf));
1800#endif
1801
1802 return;
1803invalid:
1804 invalidCommandBlock(pRI);
1805 return;
1806}
1807
Howard Sue32dbfd2015-01-07 15:55:57 +08001808static void dispatchNVReadItem(Parcel &p, RequestInfo *pRI) {
1809 RIL_NV_ReadItem nvri;
1810 int32_t t;
1811 status_t status;
1812
1813 memset(&nvri, 0, sizeof(nvri));
1814
1815 status = p.readInt32(&t);
1816 nvri.itemID = (RIL_NV_Item) t;
1817
1818 if (status != NO_ERROR) {
1819 goto invalid;
1820 }
1821
1822 startRequest;
1823 appendPrintBuf("%snvri.itemID=%d, ", printBuf, nvri.itemID);
1824 closeRequest;
1825
1826 printRequest(pRI->token, pRI->pCI->requestNumber);
1827
1828 CALL_ONREQUEST(pRI->pCI->requestNumber, &nvri, sizeof(nvri), pRI, pRI->socket_id);
1829
1830#ifdef MEMSET_FREED
1831 memset(&nvri, 0, sizeof(nvri));
1832#endif
1833
1834 return;
1835
1836invalid:
1837 invalidCommandBlock(pRI);
1838 return;
1839}
1840
1841static void dispatchNVWriteItem(Parcel &p, RequestInfo *pRI) {
1842 RIL_NV_WriteItem nvwi;
1843 int32_t t;
1844 status_t status;
1845
1846 memset(&nvwi, 0, sizeof(nvwi));
1847
1848 status = p.readInt32(&t);
1849 nvwi.itemID = (RIL_NV_Item) t;
1850
1851 nvwi.value = strdupReadString(p);
1852
1853 if (status != NO_ERROR || nvwi.value == NULL) {
1854 goto invalid;
1855 }
1856
1857 startRequest;
1858 appendPrintBuf("%snvwi.itemID=%d, value=%s, ", printBuf, nvwi.itemID,
1859 nvwi.value);
1860 closeRequest;
1861
1862 printRequest(pRI->token, pRI->pCI->requestNumber);
1863
1864 CALL_ONREQUEST(pRI->pCI->requestNumber, &nvwi, sizeof(nvwi), pRI, pRI->socket_id);
1865
1866#ifdef MEMSET_FREED
1867 memsetString(nvwi.value);
1868#endif
1869
1870 free(nvwi.value);
1871
1872#ifdef MEMSET_FREED
1873 memset(&nvwi, 0, sizeof(nvwi));
1874#endif
1875
1876 return;
1877
1878invalid:
1879 invalidCommandBlock(pRI);
1880 return;
1881}
1882
1883
1884static void dispatchUiccSubscripton(Parcel &p, RequestInfo *pRI) {
1885 RIL_SelectUiccSub uicc_sub;
1886 status_t status;
1887 int32_t t;
1888 memset(&uicc_sub, 0, sizeof(uicc_sub));
1889
1890 status = p.readInt32(&t);
1891 if (status != NO_ERROR) {
1892 goto invalid;
1893 }
1894 uicc_sub.slot = (int) t;
1895
1896 status = p.readInt32(&t);
1897 if (status != NO_ERROR) {
1898 goto invalid;
1899 }
1900 uicc_sub.app_index = (int) t;
1901
1902 status = p.readInt32(&t);
1903 if (status != NO_ERROR) {
1904 goto invalid;
1905 }
1906 uicc_sub.sub_type = (RIL_SubscriptionType) t;
1907
1908 status = p.readInt32(&t);
1909 if (status != NO_ERROR) {
1910 goto invalid;
1911 }
1912 uicc_sub.act_status = (RIL_UiccSubActStatus) t;
1913
1914 startRequest;
1915 appendPrintBuf("slot=%d, app_index=%d, act_status = %d", uicc_sub.slot, uicc_sub.app_index,
1916 uicc_sub.act_status);
1917 RLOGD("dispatchUiccSubscription, slot=%d, app_index=%d, act_status = %d", uicc_sub.slot,
1918 uicc_sub.app_index, uicc_sub.act_status);
1919 closeRequest;
1920 printRequest(pRI->token, pRI->pCI->requestNumber);
1921
1922 CALL_ONREQUEST(pRI->pCI->requestNumber, &uicc_sub, sizeof(uicc_sub), pRI, pRI->socket_id);
1923
1924#ifdef MEMSET_FREED
1925 memset(&uicc_sub, 0, sizeof(uicc_sub));
1926#endif
1927 return;
1928
1929invalid:
1930 invalidCommandBlock(pRI);
1931 return;
1932}
1933
1934static void dispatchSimAuthentication(Parcel &p, RequestInfo *pRI)
1935{
1936 RIL_SimAuthentication pf;
1937 int32_t t;
1938 status_t status;
1939
1940 memset(&pf, 0, sizeof(pf));
1941
1942 status = p.readInt32(&t);
1943 pf.authContext = (int) t;
1944 pf.authData = strdupReadString(p);
1945 pf.aid = strdupReadString(p);
1946
1947 startRequest;
Andreas Schneidera8d09502015-06-23 18:41:38 +02001948 appendPrintBuf("authContext=%d, authData=%s, aid=%s", pf.authContext, pf.authData, pf.aid);
Howard Sue32dbfd2015-01-07 15:55:57 +08001949 closeRequest;
1950 printRequest(pRI->token, pRI->pCI->requestNumber);
1951
1952 if (status != NO_ERROR) {
1953 goto invalid;
1954 }
1955 CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, pRI->socket_id);
1956
1957#ifdef MEMSET_FREED
1958 memsetString(pf.authData);
1959 memsetString(pf.aid);
1960#endif
1961
1962 free(pf.authData);
1963 free(pf.aid);
1964
1965#ifdef MEMSET_FREED
1966 memset(&pf, 0, sizeof(pf));
1967#endif
1968
1969 return;
1970invalid:
1971 invalidCommandBlock(pRI);
1972 return;
1973}
1974
1975static void dispatchDataProfile(Parcel &p, RequestInfo *pRI) {
1976 int32_t t;
1977 status_t status;
1978 int32_t num;
1979
1980 status = p.readInt32(&num);
1981 if (status != NO_ERROR) {
1982 goto invalid;
1983 }
1984
1985 {
1986 RIL_DataProfileInfo dataProfiles[num];
1987 RIL_DataProfileInfo *dataProfilePtrs[num];
1988
1989 startRequest;
1990 for (int i = 0 ; i < num ; i++ ) {
1991 dataProfilePtrs[i] = &dataProfiles[i];
1992
1993 status = p.readInt32(&t);
1994 dataProfiles[i].profileId = (int) t;
1995
1996 dataProfiles[i].apn = strdupReadString(p);
1997 dataProfiles[i].protocol = strdupReadString(p);
1998 status = p.readInt32(&t);
1999 dataProfiles[i].authType = (int) t;
2000
2001 dataProfiles[i].user = strdupReadString(p);
2002 dataProfiles[i].password = strdupReadString(p);
2003
2004 status = p.readInt32(&t);
2005 dataProfiles[i].type = (int) t;
2006
2007 status = p.readInt32(&t);
2008 dataProfiles[i].maxConnsTime = (int) t;
2009 status = p.readInt32(&t);
2010 dataProfiles[i].maxConns = (int) t;
2011 status = p.readInt32(&t);
2012 dataProfiles[i].waitTime = (int) t;
2013
2014 status = p.readInt32(&t);
2015 dataProfiles[i].enabled = (int) t;
2016
2017 appendPrintBuf("%s [%d: profileId=%d, apn =%s, protocol =%s, authType =%d, \
2018 user =%s, password =%s, type =%d, maxConnsTime =%d, maxConns =%d, \
2019 waitTime =%d, enabled =%d]", printBuf, i, dataProfiles[i].profileId,
2020 dataProfiles[i].apn, dataProfiles[i].protocol, dataProfiles[i].authType,
2021 dataProfiles[i].user, dataProfiles[i].password, dataProfiles[i].type,
2022 dataProfiles[i].maxConnsTime, dataProfiles[i].maxConns,
2023 dataProfiles[i].waitTime, dataProfiles[i].enabled);
2024 }
2025 closeRequest;
2026 printRequest(pRI->token, pRI->pCI->requestNumber);
2027
2028 if (status != NO_ERROR) {
2029 goto invalid;
2030 }
2031 CALL_ONREQUEST(pRI->pCI->requestNumber,
2032 dataProfilePtrs,
2033 num * sizeof(RIL_DataProfileInfo *),
2034 pRI, pRI->socket_id);
2035
2036#ifdef MEMSET_FREED
2037 memset(dataProfiles, 0, num * sizeof(RIL_DataProfileInfo));
2038 memset(dataProfilePtrs, 0, num * sizeof(RIL_DataProfileInfo *));
2039#endif
2040 }
2041
2042 return;
2043
2044invalid:
2045 invalidCommandBlock(pRI);
2046 return;
2047}
2048
Howard Subd82ef12015-04-12 10:25:05 +02002049static void dispatchRadioCapability(Parcel &p, RequestInfo *pRI){
2050 RIL_RadioCapability rc;
2051 int32_t t;
2052 status_t status;
2053
2054 memset (&rc, 0, sizeof(RIL_RadioCapability));
2055
2056 status = p.readInt32(&t);
2057 rc.version = (int)t;
2058 if (status != NO_ERROR) {
2059 goto invalid;
2060 }
2061
2062 status = p.readInt32(&t);
2063 rc.session= (int)t;
2064 if (status != NO_ERROR) {
2065 goto invalid;
2066 }
2067
2068 status = p.readInt32(&t);
2069 rc.phase= (int)t;
2070 if (status != NO_ERROR) {
2071 goto invalid;
2072 }
2073
2074 status = p.readInt32(&t);
2075 rc.rat = (int)t;
2076 if (status != NO_ERROR) {
2077 goto invalid;
2078 }
2079
2080 status = readStringFromParcelInplace(p, rc.logicalModemUuid, sizeof(rc.logicalModemUuid));
2081 if (status != NO_ERROR) {
2082 goto invalid;
2083 }
2084
2085 status = p.readInt32(&t);
2086 rc.status = (int)t;
2087
2088 if (status != NO_ERROR) {
2089 goto invalid;
2090 }
2091
2092 startRequest;
2093 appendPrintBuf("%s [version:%d, session:%d, phase:%d, rat:%d, \
Andreas Schneidera8d09502015-06-23 18:41:38 +02002094 logicalModemUuid:%s, status:%d", printBuf, rc.version, rc.session,
2095 rc.phase, rc.rat, rc.logicalModemUuid, rc.status);
Howard Subd82ef12015-04-12 10:25:05 +02002096
2097 closeRequest;
2098 printRequest(pRI->token, pRI->pCI->requestNumber);
2099
2100 CALL_ONREQUEST(pRI->pCI->requestNumber,
2101 &rc,
2102 sizeof(RIL_RadioCapability),
2103 pRI, pRI->socket_id);
2104 return;
2105invalid:
2106 invalidCommandBlock(pRI);
2107 return;
2108}
2109
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002110static int
2111blockingWrite(int fd, const void *buffer, size_t len) {
2112 size_t writeOffset = 0;
2113 const uint8_t *toWrite;
2114
2115 toWrite = (const uint8_t *)buffer;
2116
2117 while (writeOffset < len) {
2118 ssize_t written;
2119 do {
2120 written = write (fd, toWrite + writeOffset,
2121 len - writeOffset);
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002122 } while (written < 0 && ((errno == EINTR) || (errno == EAGAIN)));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002123
2124 if (written >= 0) {
2125 writeOffset += written;
2126 } else { // written < 0
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002127 RLOGE ("RIL Response: unexpected error on write errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002128 close(fd);
2129 return -1;
2130 }
2131 }
Robert Greenwaltbc29c432015-04-29 16:57:39 -07002132#if VDBG
Dheeraj Shettycc231012014-07-02 21:27:57 +02002133 RLOGE("RIL Response bytes written:%d", writeOffset);
Robert Greenwaltbc29c432015-04-29 16:57:39 -07002134#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002135 return 0;
2136}
2137
2138static int
Howard Sue32dbfd2015-01-07 15:55:57 +08002139sendResponseRaw (const void *data, size_t dataSize, RIL_SOCKET_ID socket_id) {
2140 int fd = s_ril_param_socket.fdCommand;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002141 int ret;
2142 uint32_t header;
Howard Sue32dbfd2015-01-07 15:55:57 +08002143 pthread_mutex_t * writeMutexHook = &s_writeMutex;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002144
Robert Greenwaltbc29c432015-04-29 16:57:39 -07002145#if VDBG
Andreas Schneider822b70b2015-10-23 08:36:26 +02002146 RLOGD("Send Response to %s", rilSocketIdToString(socket_id));
Robert Greenwaltbc29c432015-04-29 16:57:39 -07002147#endif
Howard Sue32dbfd2015-01-07 15:55:57 +08002148
2149#if (SIM_COUNT >= 2)
2150 if (socket_id == RIL_SOCKET_2) {
2151 fd = s_ril_param_socket2.fdCommand;
2152 writeMutexHook = &s_writeMutex_socket2;
2153 }
2154#if (SIM_COUNT >= 3)
2155 else if (socket_id == RIL_SOCKET_3) {
2156 fd = s_ril_param_socket3.fdCommand;
2157 writeMutexHook = &s_writeMutex_socket3;
2158 }
2159#endif
2160#if (SIM_COUNT >= 4)
2161 else if (socket_id == RIL_SOCKET_4) {
2162 fd = s_ril_param_socket4.fdCommand;
2163 writeMutexHook = &s_writeMutex_socket4;
2164 }
2165#endif
2166#endif
2167 if (fd < 0) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002168 return -1;
2169 }
2170
Howard Subd82ef12015-04-12 10:25:05 +02002171 if (dataSize > MAX_COMMAND_BYTES) {
2172 RLOGE("RIL: packet larger than %u (%u)",
2173 MAX_COMMAND_BYTES, (unsigned int )dataSize);
2174
2175 return -1;
2176 }
2177
Howard Sue32dbfd2015-01-07 15:55:57 +08002178 pthread_mutex_lock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002179
2180 header = htonl(dataSize);
2181
2182 ret = blockingWrite(fd, (void *)&header, sizeof(header));
2183
2184 if (ret < 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002185 pthread_mutex_unlock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002186 return ret;
2187 }
2188
2189 ret = blockingWrite(fd, data, dataSize);
2190
2191 if (ret < 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002192 pthread_mutex_unlock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002193 return ret;
2194 }
2195
Howard Sue32dbfd2015-01-07 15:55:57 +08002196 pthread_mutex_unlock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002197
2198 return 0;
2199}
2200
2201static int
Howard Sue32dbfd2015-01-07 15:55:57 +08002202sendResponse (Parcel &p, RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002203 printResponse;
Howard Sue32dbfd2015-01-07 15:55:57 +08002204 return sendResponseRaw(p.data(), p.dataSize(), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002205}
2206
Howard Sue32dbfd2015-01-07 15:55:57 +08002207/** response is an int* pointing to an array of ints */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002208
2209static int
2210responseInts(Parcel &p, void *response, size_t responselen) {
2211 int numInts;
2212
2213 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002214 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002215 return RIL_ERRNO_INVALID_RESPONSE;
2216 }
2217 if (responselen % sizeof(int) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002218 RLOGE("responseInts: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002219 (int)responselen, (int)sizeof(int));
2220 return RIL_ERRNO_INVALID_RESPONSE;
2221 }
2222
2223 int *p_int = (int *) response;
2224
Howard Sue32dbfd2015-01-07 15:55:57 +08002225 numInts = responselen / sizeof(int);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002226 p.writeInt32 (numInts);
2227
2228 /* each int*/
2229 startResponse;
2230 for (int i = 0 ; i < numInts ; i++) {
2231 appendPrintBuf("%s%d,", printBuf, p_int[i]);
2232 p.writeInt32(p_int[i]);
2233 }
2234 removeLastChar;
2235 closeResponse;
2236
2237 return 0;
2238}
2239
Daniel Hillenbrandd0b84162015-04-12 11:53:23 +02002240static int
2241responseIntsGetPreferredNetworkType(Parcel &p, void *response, size_t responselen) {
2242 int numInts;
2243
2244 if (response == NULL && responselen != 0) {
2245 RLOGE("invalid response: NULL");
2246 return RIL_ERRNO_INVALID_RESPONSE;
2247 }
2248 if (responselen % sizeof(int) != 0) {
2249 RLOGE("responseInts: invalid response length %d expected multiple of %d\n",
2250 (int)responselen, (int)sizeof(int));
2251 return RIL_ERRNO_INVALID_RESPONSE;
2252 }
2253
2254 int *p_int = (int *) response;
2255
2256 numInts = responselen / sizeof(int);
2257 p.writeInt32 (numInts);
2258
2259 /* each int*/
2260 startResponse;
2261 for (int i = 0 ; i < numInts ; i++) {
2262 if (i == 0 && p_int[0] == 7) {
2263 RLOGD("REQUEST_GET_PREFERRED_NETWORK_TYPE: NETWORK_MODE_GLOBAL => NETWORK_MODE_WCDMA_PREF");
2264 p_int[0] = 0;
2265 }
2266 appendPrintBuf("%s%d,", printBuf, p_int[i]);
2267 p.writeInt32(p_int[i]);
2268 }
2269 removeLastChar;
2270 closeResponse;
2271
2272 return 0;
2273}
2274
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002275/** response is a char **, pointing to an array of char *'s
2276 The parcel will begin with the version */
2277static int responseStringsWithVersion(int version, Parcel &p, void *response, size_t responselen) {
2278 p.writeInt32(version);
2279 return responseStrings(p, response, responselen);
2280}
2281
2282/** response is a char **, pointing to an array of char *'s */
2283static int responseStrings(Parcel &p, void *response, size_t responselen) {
2284 return responseStrings(p, response, responselen, false);
2285}
2286
Utkarsh Guptaf7a63e52015-05-10 16:53:37 +05302287static int responseStringsNetworks(Parcel &p, void *response, size_t responselen) {
2288 return responseStrings(p, response, responselen, true);
2289}
2290
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002291/** response is a char **, pointing to an array of char *'s */
2292static int responseStrings(Parcel &p, void *response, size_t responselen, bool network_search) {
2293 int numStrings;
2294
2295 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002296 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002297 return RIL_ERRNO_INVALID_RESPONSE;
2298 }
2299 if (responselen % sizeof(char *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002300 RLOGE("responseStrings: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002301 (int)responselen, (int)sizeof(char *));
2302 return RIL_ERRNO_INVALID_RESPONSE;
2303 }
2304
2305 if (response == NULL) {
2306 p.writeInt32 (0);
2307 } else {
2308 char **p_cur = (char **) response;
2309
2310 numStrings = responselen / sizeof(char *);
Utkarsh Guptaf7a63e52015-05-10 16:53:37 +05302311 if (network_search) {
Andreas Schneiderd806de92015-10-22 16:20:51 +02002312 int32_t QANElements;
2313
2314 /*
2315 * This needs to be set to same value as mQANElements in the RIL
2316 * Telephony class.
2317 */
2318 QANElements = property_get_int32(PROPERTY_QAN_ELEMENTS, 4);
2319 p.writeInt32 ((numStrings / 5) * QANElements);
Utkarsh Guptaf7a63e52015-05-10 16:53:37 +05302320 } else {
2321 p.writeInt32 (numStrings);
2322 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002323
2324 /* each string*/
2325 startResponse;
2326 for (int i = 0 ; i < numStrings ; i++) {
NBruderman72edd422015-06-08 15:54:55 +03002327 if (network_search && ((i + 1) % 5 == 0))
Utkarsh Guptaf7a63e52015-05-10 16:53:37 +05302328 continue;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002329 appendPrintBuf("%s%s,", printBuf, (char*)p_cur[i]);
2330 writeStringToParcel (p, p_cur[i]);
2331 }
2332 removeLastChar;
2333 closeResponse;
2334 }
2335 return 0;
2336}
2337
Howard Subd82ef12015-04-12 10:25:05 +02002338
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002339/**
2340 * NULL strings are accepted
2341 * FIXME currently ignores responselen
2342 */
2343static int responseString(Parcel &p, void *response, size_t responselen) {
2344 /* one string only */
2345 startResponse;
2346 appendPrintBuf("%s%s", printBuf, (char*)response);
2347 closeResponse;
2348
2349 writeStringToParcel(p, (const char *)response);
2350
2351 return 0;
2352}
2353
2354static int responseVoid(Parcel &p, void *response, size_t responselen) {
2355 startResponse;
2356 removeLastChar;
2357 return 0;
2358}
2359
2360static int responseCallList(Parcel &p, void *response, size_t responselen) {
2361 int num;
2362
2363 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002364 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002365 return RIL_ERRNO_INVALID_RESPONSE;
2366 }
2367
2368 if (responselen % sizeof (RIL_Call *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002369 RLOGE("responseCallList: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002370 (int)responselen, (int)sizeof (RIL_Call *));
2371 return RIL_ERRNO_INVALID_RESPONSE;
2372 }
2373
2374 startResponse;
2375 /* number of call info's */
2376 num = responselen / sizeof(RIL_Call *);
2377 p.writeInt32(num);
2378
2379 for (int i = 0 ; i < num ; i++) {
2380 RIL_Call *p_cur = ((RIL_Call **) response)[i];
2381 /* each call info */
2382 p.writeInt32(p_cur->state);
2383 p.writeInt32(p_cur->index);
2384 p.writeInt32(p_cur->toa);
2385 p.writeInt32(p_cur->isMpty);
2386 p.writeInt32(p_cur->isMT);
2387 p.writeInt32(p_cur->als);
2388 p.writeInt32(p_cur->isVoice);
Andreas Schneider29472682015-01-01 19:00:04 +01002389
Sayd1052772015-12-13 17:25:01 +09002390#if defined(MODEM_TYPE_XMM7260) || defined(MODEM_TYPE_M7450) || defined(MODEM_TYPE_SS333)
2391#ifndef MODEM_TYPE_SS333
Andreas Schneider29472682015-01-01 19:00:04 +01002392 p.writeInt32(p_cur->isVideo);
Sayd1052772015-12-13 17:25:01 +09002393#endif
Andreas Schneider29472682015-01-01 19:00:04 +01002394
2395 /* Pass CallDetails */
2396 p.writeInt32(0);
2397 p.writeInt32(0);
2398 writeStringToParcel(p, "");
2399#endif
2400
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002401 p.writeInt32(p_cur->isVoicePrivacy);
2402 writeStringToParcel(p, p_cur->number);
2403 p.writeInt32(p_cur->numberPresentation);
2404 writeStringToParcel(p, p_cur->name);
2405 p.writeInt32(p_cur->namePresentation);
2406 // Remove when partners upgrade to version 3
2407 if ((s_callbacks.version < 3) || (p_cur->uusInfo == NULL || p_cur->uusInfo->uusData == NULL)) {
2408 p.writeInt32(0); /* UUS Information is absent */
2409 } else {
2410 RIL_UUS_Info *uusInfo = p_cur->uusInfo;
2411 p.writeInt32(1); /* UUS Information is present */
2412 p.writeInt32(uusInfo->uusType);
2413 p.writeInt32(uusInfo->uusDcs);
2414 p.writeInt32(uusInfo->uusLength);
2415 p.write(uusInfo->uusData, uusInfo->uusLength);
2416 }
2417 appendPrintBuf("%s[id=%d,%s,toa=%d,",
2418 printBuf,
2419 p_cur->index,
2420 callStateToString(p_cur->state),
2421 p_cur->toa);
2422 appendPrintBuf("%s%s,%s,als=%d,%s,%s,",
2423 printBuf,
2424 (p_cur->isMpty)?"conf":"norm",
2425 (p_cur->isMT)?"mt":"mo",
2426 p_cur->als,
2427 (p_cur->isVoice)?"voc":"nonvoc",
2428 (p_cur->isVoicePrivacy)?"evp":"noevp");
Sayd1052772015-12-13 17:25:01 +09002429#if defined(MODEM_TYPE_XMM7260) || defined(MODEM_TYPE_M7450) || defined(MODEM_TYPE_SS333)
Andreas Schneider29472682015-01-01 19:00:04 +01002430 appendPrintBuf("%s,%s,",
2431 printBuf,
2432 (p_cur->isVideo) ? "vid" : "novid");
2433#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002434 appendPrintBuf("%s%s,cli=%d,name='%s',%d]",
2435 printBuf,
2436 p_cur->number,
2437 p_cur->numberPresentation,
2438 p_cur->name,
2439 p_cur->namePresentation);
2440 }
2441 removeLastChar;
2442 closeResponse;
2443
2444 return 0;
2445}
2446
2447static int responseSMS(Parcel &p, void *response, size_t responselen) {
2448 if (response == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002449 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002450 return RIL_ERRNO_INVALID_RESPONSE;
2451 }
2452
2453 if (responselen != sizeof (RIL_SMS_Response) ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002454 RLOGE("invalid response length %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002455 (int)responselen, (int)sizeof (RIL_SMS_Response));
2456 return RIL_ERRNO_INVALID_RESPONSE;
2457 }
2458
2459 RIL_SMS_Response *p_cur = (RIL_SMS_Response *) response;
2460
2461 p.writeInt32(p_cur->messageRef);
2462 writeStringToParcel(p, p_cur->ackPDU);
2463 p.writeInt32(p_cur->errorCode);
2464
2465 startResponse;
2466 appendPrintBuf("%s%d,%s,%d", printBuf, p_cur->messageRef,
2467 (char*)p_cur->ackPDU, p_cur->errorCode);
2468 closeResponse;
2469
2470 return 0;
2471}
2472
2473static int responseDataCallListV4(Parcel &p, void *response, size_t responselen)
2474{
2475 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002476 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002477 return RIL_ERRNO_INVALID_RESPONSE;
2478 }
2479
2480 if (responselen % sizeof(RIL_Data_Call_Response_v4) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002481 RLOGE("responseDataCallListV4: invalid response length %d expected multiple of %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002482 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v4));
2483 return RIL_ERRNO_INVALID_RESPONSE;
2484 }
2485
Howard Sue32dbfd2015-01-07 15:55:57 +08002486 // Write version
2487 p.writeInt32(4);
2488
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002489 int num = responselen / sizeof(RIL_Data_Call_Response_v4);
2490 p.writeInt32(num);
2491
2492 RIL_Data_Call_Response_v4 *p_cur = (RIL_Data_Call_Response_v4 *) response;
2493 startResponse;
2494 int i;
2495 for (i = 0; i < num; i++) {
2496 p.writeInt32(p_cur[i].cid);
2497 p.writeInt32(p_cur[i].active);
2498 writeStringToParcel(p, p_cur[i].type);
2499 // apn is not used, so don't send.
2500 writeStringToParcel(p, p_cur[i].address);
2501 appendPrintBuf("%s[cid=%d,%s,%s,%s],", printBuf,
2502 p_cur[i].cid,
2503 (p_cur[i].active==0)?"down":"up",
2504 (char*)p_cur[i].type,
2505 (char*)p_cur[i].address);
2506 }
2507 removeLastChar;
2508 closeResponse;
2509
2510 return 0;
2511}
2512
Howard Sue32dbfd2015-01-07 15:55:57 +08002513static int responseDataCallListV6(Parcel &p, void *response, size_t responselen)
2514{
2515 if (response == NULL && responselen != 0) {
2516 RLOGE("invalid response: NULL");
2517 return RIL_ERRNO_INVALID_RESPONSE;
2518 }
2519
2520 if (responselen % sizeof(RIL_Data_Call_Response_v6) != 0) {
2521 RLOGE("responseDataCallListV6: invalid response length %d expected multiple of %d",
2522 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v6));
2523 return RIL_ERRNO_INVALID_RESPONSE;
2524 }
2525
2526 // Write version
2527 p.writeInt32(6);
2528
2529 int num = responselen / sizeof(RIL_Data_Call_Response_v6);
2530 p.writeInt32(num);
2531
2532 RIL_Data_Call_Response_v6 *p_cur = (RIL_Data_Call_Response_v6 *) response;
2533 startResponse;
2534 int i;
2535 for (i = 0; i < num; i++) {
2536 p.writeInt32((int)p_cur[i].status);
2537 p.writeInt32(p_cur[i].suggestedRetryTime);
2538 p.writeInt32(p_cur[i].cid);
2539 p.writeInt32(p_cur[i].active);
2540 writeStringToParcel(p, p_cur[i].type);
2541 writeStringToParcel(p, p_cur[i].ifname);
2542 writeStringToParcel(p, p_cur[i].addresses);
2543 writeStringToParcel(p, p_cur[i].dnses);
2544 writeStringToParcel(p, p_cur[i].addresses);
2545 appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s],", printBuf,
2546 p_cur[i].status,
2547 p_cur[i].suggestedRetryTime,
2548 p_cur[i].cid,
2549 (p_cur[i].active==0)?"down":"up",
2550 (char*)p_cur[i].type,
2551 (char*)p_cur[i].ifname,
2552 (char*)p_cur[i].addresses,
2553 (char*)p_cur[i].dnses,
2554 (char*)p_cur[i].addresses);
2555 }
2556 removeLastChar;
2557 closeResponse;
2558
2559 return 0;
2560}
2561
Howard Subd82ef12015-04-12 10:25:05 +02002562static int responseDataCallListV9(Parcel &p, void *response, size_t responselen)
2563{
2564 if (response == NULL && responselen != 0) {
2565 RLOGE("invalid response: NULL");
2566 return RIL_ERRNO_INVALID_RESPONSE;
2567 }
2568
2569 if (responselen % sizeof(RIL_Data_Call_Response_v9) != 0) {
2570 RLOGE("responseDataCallListV9: invalid response length %d expected multiple of %d",
2571 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v9));
2572 return RIL_ERRNO_INVALID_RESPONSE;
2573 }
2574
2575 // Write version
2576 p.writeInt32(10);
2577
2578 int num = responselen / sizeof(RIL_Data_Call_Response_v9);
2579 p.writeInt32(num);
2580
2581 RIL_Data_Call_Response_v9 *p_cur = (RIL_Data_Call_Response_v9 *) response;
2582 startResponse;
2583 int i;
2584 for (i = 0; i < num; i++) {
2585 p.writeInt32((int)p_cur[i].status);
2586 p.writeInt32(p_cur[i].suggestedRetryTime);
2587 p.writeInt32(p_cur[i].cid);
2588 p.writeInt32(p_cur[i].active);
2589 writeStringToParcel(p, p_cur[i].type);
2590 writeStringToParcel(p, p_cur[i].ifname);
2591 writeStringToParcel(p, p_cur[i].addresses);
2592 writeStringToParcel(p, p_cur[i].dnses);
2593 writeStringToParcel(p, p_cur[i].gateways);
2594 writeStringToParcel(p, p_cur[i].pcscf);
2595 appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s],", printBuf,
2596 p_cur[i].status,
2597 p_cur[i].suggestedRetryTime,
2598 p_cur[i].cid,
2599 (p_cur[i].active==0)?"down":"up",
2600 (char*)p_cur[i].type,
2601 (char*)p_cur[i].ifname,
2602 (char*)p_cur[i].addresses,
2603 (char*)p_cur[i].dnses,
2604 (char*)p_cur[i].gateways,
2605 (char*)p_cur[i].pcscf);
2606 }
2607 removeLastChar;
2608 closeResponse;
2609
2610 return 0;
2611}
2612
2613
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002614static int responseDataCallList(Parcel &p, void *response, size_t responselen)
2615{
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002616 if (s_callbacks.version < 5) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002617 RLOGD("responseDataCallList: v4");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002618 return responseDataCallListV4(p, response, responselen);
Howard Subd82ef12015-04-12 10:25:05 +02002619 } else if (responselen % sizeof(RIL_Data_Call_Response_v6) == 0) {
2620 return responseDataCallListV6(p, response, responselen);
2621 } else if (responselen % sizeof(RIL_Data_Call_Response_v9) == 0) {
2622 return responseDataCallListV9(p, response, responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002623 } else {
2624 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002625 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002626 return RIL_ERRNO_INVALID_RESPONSE;
2627 }
2628
Howard Subd82ef12015-04-12 10:25:05 +02002629 if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) {
2630 RLOGE("invalid response length %d expected multiple of %d",
2631 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v11));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002632 return RIL_ERRNO_INVALID_RESPONSE;
2633 }
2634
Howard Sue32dbfd2015-01-07 15:55:57 +08002635 // Write version
Howard Subd82ef12015-04-12 10:25:05 +02002636 p.writeInt32(11);
Howard Sue32dbfd2015-01-07 15:55:57 +08002637
Howard Subd82ef12015-04-12 10:25:05 +02002638 int num = responselen / sizeof(RIL_Data_Call_Response_v11);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002639 p.writeInt32(num);
2640
Howard Subd82ef12015-04-12 10:25:05 +02002641 RIL_Data_Call_Response_v11 *p_cur = (RIL_Data_Call_Response_v11 *) response;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002642 startResponse;
2643 int i;
2644 for (i = 0; i < num; i++) {
2645 p.writeInt32((int)p_cur[i].status);
2646 p.writeInt32(p_cur[i].suggestedRetryTime);
2647 p.writeInt32(p_cur[i].cid);
2648 p.writeInt32(p_cur[i].active);
2649 writeStringToParcel(p, p_cur[i].type);
2650 writeStringToParcel(p, p_cur[i].ifname);
2651 writeStringToParcel(p, p_cur[i].addresses);
2652 writeStringToParcel(p, p_cur[i].dnses);
Howard Sue32dbfd2015-01-07 15:55:57 +08002653 writeStringToParcel(p, p_cur[i].gateways);
2654 writeStringToParcel(p, p_cur[i].pcscf);
Howard Subd82ef12015-04-12 10:25:05 +02002655 p.writeInt32(p_cur[i].mtu);
2656 appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s,mtu=%d],", printBuf,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002657 p_cur[i].status,
2658 p_cur[i].suggestedRetryTime,
2659 p_cur[i].cid,
2660 (p_cur[i].active==0)?"down":"up",
2661 (char*)p_cur[i].type,
2662 (char*)p_cur[i].ifname,
2663 (char*)p_cur[i].addresses,
2664 (char*)p_cur[i].dnses,
Howard Sue32dbfd2015-01-07 15:55:57 +08002665 (char*)p_cur[i].gateways,
Howard Subd82ef12015-04-12 10:25:05 +02002666 (char*)p_cur[i].pcscf,
2667 p_cur[i].mtu);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002668 }
2669 removeLastChar;
2670 closeResponse;
2671 }
2672
2673 return 0;
2674}
2675
2676static int responseSetupDataCall(Parcel &p, void *response, size_t responselen)
2677{
2678 if (s_callbacks.version < 5) {
2679 return responseStringsWithVersion(s_callbacks.version, p, response, responselen);
2680 } else {
2681 return responseDataCallList(p, response, responselen);
2682 }
2683}
2684
2685static int responseRaw(Parcel &p, void *response, size_t responselen) {
2686 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002687 RLOGE("invalid response: NULL with responselen != 0");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002688 return RIL_ERRNO_INVALID_RESPONSE;
2689 }
2690
2691 // The java code reads -1 size as null byte array
2692 if (response == NULL) {
2693 p.writeInt32(-1);
2694 } else {
2695 p.writeInt32(responselen);
2696 p.write(response, responselen);
2697 }
2698
2699 return 0;
2700}
2701
2702
2703static int responseSIM_IO(Parcel &p, void *response, size_t responselen) {
2704 if (response == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002705 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002706 return RIL_ERRNO_INVALID_RESPONSE;
2707 }
2708
2709 if (responselen != sizeof (RIL_SIM_IO_Response) ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002710 RLOGE("invalid response length was %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002711 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
2712 return RIL_ERRNO_INVALID_RESPONSE;
2713 }
2714
2715 RIL_SIM_IO_Response *p_cur = (RIL_SIM_IO_Response *) response;
2716 p.writeInt32(p_cur->sw1);
2717 p.writeInt32(p_cur->sw2);
2718 writeStringToParcel(p, p_cur->simResponse);
2719
2720 startResponse;
2721 appendPrintBuf("%ssw1=0x%X,sw2=0x%X,%s", printBuf, p_cur->sw1, p_cur->sw2,
2722 (char*)p_cur->simResponse);
2723 closeResponse;
2724
2725
2726 return 0;
2727}
2728
2729static int responseCallForwards(Parcel &p, void *response, size_t responselen) {
2730 int num;
2731
2732 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002733 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002734 return RIL_ERRNO_INVALID_RESPONSE;
2735 }
2736
2737 if (responselen % sizeof(RIL_CallForwardInfo *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002738 RLOGE("responseCallForwards: invalid response length %d expected multiple of %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002739 (int)responselen, (int)sizeof(RIL_CallForwardInfo *));
2740 return RIL_ERRNO_INVALID_RESPONSE;
2741 }
2742
2743 /* number of call info's */
2744 num = responselen / sizeof(RIL_CallForwardInfo *);
2745 p.writeInt32(num);
2746
2747 startResponse;
2748 for (int i = 0 ; i < num ; i++) {
2749 RIL_CallForwardInfo *p_cur = ((RIL_CallForwardInfo **) response)[i];
2750
2751 p.writeInt32(p_cur->status);
2752 p.writeInt32(p_cur->reason);
2753 p.writeInt32(p_cur->serviceClass);
2754 p.writeInt32(p_cur->toa);
2755 writeStringToParcel(p, p_cur->number);
2756 p.writeInt32(p_cur->timeSeconds);
2757 appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
2758 (p_cur->status==1)?"enable":"disable",
2759 p_cur->reason, p_cur->serviceClass, p_cur->toa,
2760 (char*)p_cur->number,
2761 p_cur->timeSeconds);
2762 }
2763 removeLastChar;
2764 closeResponse;
2765
2766 return 0;
2767}
2768
2769static int responseSsn(Parcel &p, void *response, size_t responselen) {
2770 if (response == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002771 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002772 return RIL_ERRNO_INVALID_RESPONSE;
2773 }
2774
2775 if (responselen != sizeof(RIL_SuppSvcNotification)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002776 RLOGE("invalid response length was %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002777 (int)responselen, (int)sizeof (RIL_SuppSvcNotification));
2778 return RIL_ERRNO_INVALID_RESPONSE;
2779 }
2780
2781 RIL_SuppSvcNotification *p_cur = (RIL_SuppSvcNotification *) response;
2782 p.writeInt32(p_cur->notificationType);
2783 p.writeInt32(p_cur->code);
2784 p.writeInt32(p_cur->index);
2785 p.writeInt32(p_cur->type);
2786 writeStringToParcel(p, p_cur->number);
2787
2788 startResponse;
2789 appendPrintBuf("%s%s,code=%d,id=%d,type=%d,%s", printBuf,
2790 (p_cur->notificationType==0)?"mo":"mt",
2791 p_cur->code, p_cur->index, p_cur->type,
2792 (char*)p_cur->number);
2793 closeResponse;
2794
2795 return 0;
2796}
2797
2798static int responseCellList(Parcel &p, void *response, size_t responselen) {
2799 int num;
2800
2801 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002802 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002803 return RIL_ERRNO_INVALID_RESPONSE;
2804 }
2805
2806 if (responselen % sizeof (RIL_NeighboringCell *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002807 RLOGE("responseCellList: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002808 (int)responselen, (int)sizeof (RIL_NeighboringCell *));
2809 return RIL_ERRNO_INVALID_RESPONSE;
2810 }
2811
2812 startResponse;
2813 /* number of records */
2814 num = responselen / sizeof(RIL_NeighboringCell *);
2815 p.writeInt32(num);
2816
2817 for (int i = 0 ; i < num ; i++) {
2818 RIL_NeighboringCell *p_cur = ((RIL_NeighboringCell **) response)[i];
2819
2820 p.writeInt32(p_cur->rssi);
2821 writeStringToParcel (p, p_cur->cid);
2822
2823 appendPrintBuf("%s[cid=%s,rssi=%d],", printBuf,
2824 p_cur->cid, p_cur->rssi);
2825 }
2826 removeLastChar;
2827 closeResponse;
2828
2829 return 0;
2830}
2831
2832/**
2833 * Marshall the signalInfoRecord into the parcel if it exists.
2834 */
2835static void marshallSignalInfoRecord(Parcel &p,
2836 RIL_CDMA_SignalInfoRecord &p_signalInfoRecord) {
2837 p.writeInt32(p_signalInfoRecord.isPresent);
2838 p.writeInt32(p_signalInfoRecord.signalType);
2839 p.writeInt32(p_signalInfoRecord.alertPitch);
2840 p.writeInt32(p_signalInfoRecord.signal);
2841}
2842
2843static int responseCdmaInformationRecords(Parcel &p,
2844 void *response, size_t responselen) {
2845 int num;
2846 char* string8 = NULL;
2847 int buffer_lenght;
2848 RIL_CDMA_InformationRecord *infoRec;
2849
2850 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002851 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002852 return RIL_ERRNO_INVALID_RESPONSE;
2853 }
2854
2855 if (responselen != sizeof (RIL_CDMA_InformationRecords)) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002856 RLOGE("responseCdmaInformationRecords: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002857 (int)responselen, (int)sizeof (RIL_CDMA_InformationRecords *));
2858 return RIL_ERRNO_INVALID_RESPONSE;
2859 }
2860
2861 RIL_CDMA_InformationRecords *p_cur =
2862 (RIL_CDMA_InformationRecords *) response;
2863 num = MIN(p_cur->numberOfInfoRecs, RIL_CDMA_MAX_NUMBER_OF_INFO_RECS);
2864
2865 startResponse;
2866 p.writeInt32(num);
2867
2868 for (int i = 0 ; i < num ; i++) {
2869 infoRec = &p_cur->infoRec[i];
2870 p.writeInt32(infoRec->name);
2871 switch (infoRec->name) {
2872 case RIL_CDMA_DISPLAY_INFO_REC:
2873 case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
2874 if (infoRec->rec.display.alpha_len >
2875 CDMA_ALPHA_INFO_BUFFER_LENGTH) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002876 RLOGE("invalid display info response length %d \
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002877 expected not more than %d\n",
2878 (int)infoRec->rec.display.alpha_len,
2879 CDMA_ALPHA_INFO_BUFFER_LENGTH);
2880 return RIL_ERRNO_INVALID_RESPONSE;
2881 }
2882 string8 = (char*) malloc((infoRec->rec.display.alpha_len + 1)
2883 * sizeof(char) );
2884 for (int i = 0 ; i < infoRec->rec.display.alpha_len ; i++) {
2885 string8[i] = infoRec->rec.display.alpha_buf[i];
2886 }
2887 string8[(int)infoRec->rec.display.alpha_len] = '\0';
2888 writeStringToParcel(p, (const char*)string8);
2889 free(string8);
2890 string8 = NULL;
2891 break;
2892 case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
2893 case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
2894 case RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
2895 if (infoRec->rec.number.len > CDMA_NUMBER_INFO_BUFFER_LENGTH) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002896 RLOGE("invalid display info response length %d \
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002897 expected not more than %d\n",
2898 (int)infoRec->rec.number.len,
2899 CDMA_NUMBER_INFO_BUFFER_LENGTH);
2900 return RIL_ERRNO_INVALID_RESPONSE;
2901 }
2902 string8 = (char*) malloc((infoRec->rec.number.len + 1)
2903 * sizeof(char) );
2904 for (int i = 0 ; i < infoRec->rec.number.len; i++) {
2905 string8[i] = infoRec->rec.number.buf[i];
2906 }
2907 string8[(int)infoRec->rec.number.len] = '\0';
2908 writeStringToParcel(p, (const char*)string8);
2909 free(string8);
2910 string8 = NULL;
2911 p.writeInt32(infoRec->rec.number.number_type);
2912 p.writeInt32(infoRec->rec.number.number_plan);
2913 p.writeInt32(infoRec->rec.number.pi);
2914 p.writeInt32(infoRec->rec.number.si);
2915 break;
2916 case RIL_CDMA_SIGNAL_INFO_REC:
2917 p.writeInt32(infoRec->rec.signal.isPresent);
2918 p.writeInt32(infoRec->rec.signal.signalType);
2919 p.writeInt32(infoRec->rec.signal.alertPitch);
2920 p.writeInt32(infoRec->rec.signal.signal);
2921
2922 appendPrintBuf("%sisPresent=%X, signalType=%X, \
2923 alertPitch=%X, signal=%X, ",
2924 printBuf, (int)infoRec->rec.signal.isPresent,
2925 (int)infoRec->rec.signal.signalType,
2926 (int)infoRec->rec.signal.alertPitch,
2927 (int)infoRec->rec.signal.signal);
2928 removeLastChar;
2929 break;
2930 case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
2931 if (infoRec->rec.redir.redirectingNumber.len >
2932 CDMA_NUMBER_INFO_BUFFER_LENGTH) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002933 RLOGE("invalid display info response length %d \
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002934 expected not more than %d\n",
2935 (int)infoRec->rec.redir.redirectingNumber.len,
2936 CDMA_NUMBER_INFO_BUFFER_LENGTH);
2937 return RIL_ERRNO_INVALID_RESPONSE;
2938 }
2939 string8 = (char*) malloc((infoRec->rec.redir.redirectingNumber
2940 .len + 1) * sizeof(char) );
2941 for (int i = 0;
2942 i < infoRec->rec.redir.redirectingNumber.len;
2943 i++) {
2944 string8[i] = infoRec->rec.redir.redirectingNumber.buf[i];
2945 }
2946 string8[(int)infoRec->rec.redir.redirectingNumber.len] = '\0';
2947 writeStringToParcel(p, (const char*)string8);
2948 free(string8);
2949 string8 = NULL;
2950 p.writeInt32(infoRec->rec.redir.redirectingNumber.number_type);
2951 p.writeInt32(infoRec->rec.redir.redirectingNumber.number_plan);
2952 p.writeInt32(infoRec->rec.redir.redirectingNumber.pi);
2953 p.writeInt32(infoRec->rec.redir.redirectingNumber.si);
2954 p.writeInt32(infoRec->rec.redir.redirectingReason);
2955 break;
2956 case RIL_CDMA_LINE_CONTROL_INFO_REC:
2957 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPolarityIncluded);
2958 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlToggle);
2959 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlReverse);
2960 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPowerDenial);
2961
2962 appendPrintBuf("%slineCtrlPolarityIncluded=%d, \
2963 lineCtrlToggle=%d, lineCtrlReverse=%d, \
2964 lineCtrlPowerDenial=%d, ", printBuf,
2965 (int)infoRec->rec.lineCtrl.lineCtrlPolarityIncluded,
2966 (int)infoRec->rec.lineCtrl.lineCtrlToggle,
2967 (int)infoRec->rec.lineCtrl.lineCtrlReverse,
2968 (int)infoRec->rec.lineCtrl.lineCtrlPowerDenial);
2969 removeLastChar;
2970 break;
2971 case RIL_CDMA_T53_CLIR_INFO_REC:
2972 p.writeInt32((int)(infoRec->rec.clir.cause));
2973
2974 appendPrintBuf("%scause%d", printBuf, infoRec->rec.clir.cause);
2975 removeLastChar;
2976 break;
2977 case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
2978 p.writeInt32(infoRec->rec.audioCtrl.upLink);
2979 p.writeInt32(infoRec->rec.audioCtrl.downLink);
2980
2981 appendPrintBuf("%supLink=%d, downLink=%d, ", printBuf,
2982 infoRec->rec.audioCtrl.upLink,
2983 infoRec->rec.audioCtrl.downLink);
2984 removeLastChar;
2985 break;
2986 case RIL_CDMA_T53_RELEASE_INFO_REC:
2987 // TODO(Moto): See David Krause, he has the answer:)
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002988 RLOGE("RIL_CDMA_T53_RELEASE_INFO_REC: return INVALID_RESPONSE");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002989 return RIL_ERRNO_INVALID_RESPONSE;
2990 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002991 RLOGE("Incorrect name value");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002992 return RIL_ERRNO_INVALID_RESPONSE;
2993 }
2994 }
2995 closeResponse;
2996
2997 return 0;
2998}
2999
3000static int responseRilSignalStrength(Parcel &p,
3001 void *response, size_t responselen) {
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303002 int gsmSignalStrength;
3003 int cdmaDbm;
3004 int evdoDbm;
3005
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003006 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003007 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003008 return RIL_ERRNO_INVALID_RESPONSE;
3009 }
3010
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003011 if (responselen >= sizeof (RIL_SignalStrength_v5)) {
Howard Sue32dbfd2015-01-07 15:55:57 +08003012 RIL_SignalStrength_v10 *p_cur = ((RIL_SignalStrength_v10 *) response);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003013
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303014 gsmSignalStrength = p_cur->GW_SignalStrength.signalStrength & 0xFF;
Utkarsh Gupta8ede9fa2015-04-23 13:21:49 +05303015
3016#ifdef MODEM_TYPE_XMM6260
3017 if (gsmSignalStrength < 0 ||
3018 (gsmSignalStrength > 31 && p_cur->GW_SignalStrength.signalStrength != 99)) {
3019 gsmSignalStrength = p_cur->CDMA_SignalStrength.dbm;
3020 }
3021#else
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303022 if (gsmSignalStrength < 0) {
3023 gsmSignalStrength = 99;
3024 } else if (gsmSignalStrength > 31 && gsmSignalStrength != 99) {
3025 gsmSignalStrength = 31;
3026 }
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303027#endif
3028 p.writeInt32(gsmSignalStrength);
3029
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003030 p.writeInt32(p_cur->GW_SignalStrength.bitErrorRate);
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303031
Sayd1052772015-12-13 17:25:01 +09003032#if defined(MODEM_TYPE_XMM6262) || defined(MODEM_TYPE_XMM7260) \
3033 || defined(MODEM_TYPE_M7450) || defined(MODEM_TYPE_SS333)
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303034 cdmaDbm = p_cur->CDMA_SignalStrength.dbm & 0xFF;
3035 if (cdmaDbm < 0) {
3036 cdmaDbm = 99;
3037 } else if (cdmaDbm > 31 && cdmaDbm != 99) {
3038 cdmaDbm = 31;
3039 }
3040#else
Caio Schnepperec042542015-04-14 08:03:43 -03003041 cdmaDbm = p_cur->CDMA_SignalStrength.dbm;
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303042#endif
3043 p.writeInt32(cdmaDbm);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003044 p.writeInt32(p_cur->CDMA_SignalStrength.ecio);
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303045
Sayd1052772015-12-13 17:25:01 +09003046#if defined(MODEM_TYPE_XMM6262) || defined(MODEM_TYPE_XMM7260) \
3047 || defined(MODEM_TYPE_M7450) || defined(MODEM_TYPE_SS333)
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303048 evdoDbm = p_cur->EVDO_SignalStrength.dbm & 0xFF;
3049 if (evdoDbm < 0) {
3050 evdoDbm = 99;
3051 } else if (evdoDbm > 31 && evdoDbm != 99) {
3052 evdoDbm = 31;
3053 }
3054#else
3055 evdoDbm = p_cur->EVDO_SignalStrength.dbm;
3056#endif
3057 p.writeInt32(evdoDbm);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003058 p.writeInt32(p_cur->EVDO_SignalStrength.ecio);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003059 p.writeInt32(p_cur->EVDO_SignalStrength.signalNoiseRatio);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003060 if (responselen >= sizeof (RIL_SignalStrength_v6)) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003061 /*
Ethan Chend6e30652013-08-04 22:49:56 -07003062 * Fixup LTE for backwards compatibility
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003063 */
Ethan Chend6e30652013-08-04 22:49:56 -07003064 if (s_callbacks.version <= 6) {
3065 // signalStrength: -1 -> 99
3066 if (p_cur->LTE_SignalStrength.signalStrength == -1) {
3067 p_cur->LTE_SignalStrength.signalStrength = 99;
3068 }
3069 // rsrp: -1 -> INT_MAX all other negative value to positive.
3070 // So remap here
3071 if (p_cur->LTE_SignalStrength.rsrp == -1) {
3072 p_cur->LTE_SignalStrength.rsrp = INT_MAX;
3073 } else if (p_cur->LTE_SignalStrength.rsrp < -1) {
3074 p_cur->LTE_SignalStrength.rsrp = -p_cur->LTE_SignalStrength.rsrp;
3075 }
3076 // rsrq: -1 -> INT_MAX
3077 if (p_cur->LTE_SignalStrength.rsrq == -1) {
3078 p_cur->LTE_SignalStrength.rsrq = INT_MAX;
3079 }
3080 // Not remapping rssnr is already using INT_MAX
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003081
Ethan Chend6e30652013-08-04 22:49:56 -07003082 // cqi: -1 -> INT_MAX
3083 if (p_cur->LTE_SignalStrength.cqi == -1) {
3084 p_cur->LTE_SignalStrength.cqi = INT_MAX;
3085 }
3086 }
3087 p.writeInt32(p_cur->LTE_SignalStrength.signalStrength);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003088 p.writeInt32(p_cur->LTE_SignalStrength.rsrp);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003089 p.writeInt32(p_cur->LTE_SignalStrength.rsrq);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003090 p.writeInt32(p_cur->LTE_SignalStrength.rssnr);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003091 p.writeInt32(p_cur->LTE_SignalStrength.cqi);
Howard Sue32dbfd2015-01-07 15:55:57 +08003092 if (responselen >= sizeof (RIL_SignalStrength_v10)) {
3093 p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp);
3094 } else {
3095 p.writeInt32(INT_MAX);
3096 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003097 } else {
Ethan Chend6e30652013-08-04 22:49:56 -07003098 p.writeInt32(99);
3099 p.writeInt32(INT_MAX);
3100 p.writeInt32(INT_MAX);
3101 p.writeInt32(INT_MAX);
3102 p.writeInt32(INT_MAX);
Howard Sue32dbfd2015-01-07 15:55:57 +08003103 p.writeInt32(INT_MAX);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003104 }
3105
3106 startResponse;
3107 appendPrintBuf("%s[signalStrength=%d,bitErrorRate=%d,\
3108 CDMA_SS.dbm=%d,CDMA_SSecio=%d,\
3109 EVDO_SS.dbm=%d,EVDO_SS.ecio=%d,\
3110 EVDO_SS.signalNoiseRatio=%d,\
3111 LTE_SS.signalStrength=%d,LTE_SS.rsrp=%d,LTE_SS.rsrq=%d,\
Howard Sue32dbfd2015-01-07 15:55:57 +08003112 LTE_SS.rssnr=%d,LTE_SS.cqi=%d,TDSCDMA_SS.rscp=%d]",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003113 printBuf,
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303114 gsmSignalStrength,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003115 p_cur->GW_SignalStrength.bitErrorRate,
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303116 cdmaDbm,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003117 p_cur->CDMA_SignalStrength.ecio,
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303118 evdoDbm,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003119 p_cur->EVDO_SignalStrength.ecio,
3120 p_cur->EVDO_SignalStrength.signalNoiseRatio,
3121 p_cur->LTE_SignalStrength.signalStrength,
3122 p_cur->LTE_SignalStrength.rsrp,
3123 p_cur->LTE_SignalStrength.rsrq,
3124 p_cur->LTE_SignalStrength.rssnr,
Howard Sue32dbfd2015-01-07 15:55:57 +08003125 p_cur->LTE_SignalStrength.cqi,
3126 p_cur->TD_SCDMA_SignalStrength.rscp);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003127 closeResponse;
3128
3129 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003130 RLOGE("invalid response length");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003131 return RIL_ERRNO_INVALID_RESPONSE;
3132 }
3133
3134 return 0;
3135}
3136
3137static int responseCallRing(Parcel &p, void *response, size_t responselen) {
3138 if ((response == NULL) || (responselen == 0)) {
3139 return responseVoid(p, response, responselen);
3140 } else {
3141 return responseCdmaSignalInfoRecord(p, response, responselen);
3142 }
3143}
3144
3145static int responseCdmaSignalInfoRecord(Parcel &p, void *response, size_t responselen) {
3146 if (response == NULL || responselen == 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003147 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003148 return RIL_ERRNO_INVALID_RESPONSE;
3149 }
3150
3151 if (responselen != sizeof (RIL_CDMA_SignalInfoRecord)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003152 RLOGE("invalid response length %d expected sizeof (RIL_CDMA_SignalInfoRecord) of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003153 (int)responselen, (int)sizeof (RIL_CDMA_SignalInfoRecord));
3154 return RIL_ERRNO_INVALID_RESPONSE;
3155 }
3156
3157 startResponse;
3158
3159 RIL_CDMA_SignalInfoRecord *p_cur = ((RIL_CDMA_SignalInfoRecord *) response);
3160 marshallSignalInfoRecord(p, *p_cur);
3161
3162 appendPrintBuf("%s[isPresent=%d,signalType=%d,alertPitch=%d\
3163 signal=%d]",
3164 printBuf,
3165 p_cur->isPresent,
3166 p_cur->signalType,
3167 p_cur->alertPitch,
3168 p_cur->signal);
3169
3170 closeResponse;
3171 return 0;
3172}
3173
3174static int responseCdmaCallWaiting(Parcel &p, void *response,
3175 size_t responselen) {
3176 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003177 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003178 return RIL_ERRNO_INVALID_RESPONSE;
3179 }
3180
3181 if (responselen < sizeof(RIL_CDMA_CallWaiting_v6)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003182 RLOGW("Upgrade to ril version %d\n", RIL_VERSION);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003183 }
3184
3185 RIL_CDMA_CallWaiting_v6 *p_cur = ((RIL_CDMA_CallWaiting_v6 *) response);
3186
3187 writeStringToParcel(p, p_cur->number);
3188 p.writeInt32(p_cur->numberPresentation);
3189 writeStringToParcel(p, p_cur->name);
3190 marshallSignalInfoRecord(p, p_cur->signalInfoRecord);
3191
3192 if (responselen >= sizeof(RIL_CDMA_CallWaiting_v6)) {
3193 p.writeInt32(p_cur->number_type);
3194 p.writeInt32(p_cur->number_plan);
3195 } else {
3196 p.writeInt32(0);
3197 p.writeInt32(0);
3198 }
3199
3200 startResponse;
3201 appendPrintBuf("%snumber=%s,numberPresentation=%d, name=%s,\
3202 signalInfoRecord[isPresent=%d,signalType=%d,alertPitch=%d\
3203 signal=%d,number_type=%d,number_plan=%d]",
3204 printBuf,
3205 p_cur->number,
3206 p_cur->numberPresentation,
3207 p_cur->name,
3208 p_cur->signalInfoRecord.isPresent,
3209 p_cur->signalInfoRecord.signalType,
3210 p_cur->signalInfoRecord.alertPitch,
3211 p_cur->signalInfoRecord.signal,
3212 p_cur->number_type,
3213 p_cur->number_plan);
3214 closeResponse;
3215
3216 return 0;
3217}
3218
3219static int responseSimRefresh(Parcel &p, void *response, size_t responselen) {
3220 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003221 RLOGE("responseSimRefresh: invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003222 return RIL_ERRNO_INVALID_RESPONSE;
3223 }
3224
3225 startResponse;
3226 if (s_callbacks.version == 7) {
3227 RIL_SimRefreshResponse_v7 *p_cur = ((RIL_SimRefreshResponse_v7 *) response);
3228 p.writeInt32(p_cur->result);
3229 p.writeInt32(p_cur->ef_id);
3230 writeStringToParcel(p, p_cur->aid);
3231
3232 appendPrintBuf("%sresult=%d, ef_id=%d, aid=%s",
3233 printBuf,
3234 p_cur->result,
3235 p_cur->ef_id,
3236 p_cur->aid);
3237 } else {
3238 int *p_cur = ((int *) response);
3239 p.writeInt32(p_cur[0]);
3240 p.writeInt32(p_cur[1]);
3241 writeStringToParcel(p, NULL);
3242
3243 appendPrintBuf("%sresult=%d, ef_id=%d",
3244 printBuf,
3245 p_cur[0],
3246 p_cur[1]);
3247 }
3248 closeResponse;
3249
3250 return 0;
3251}
3252
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003253static int responseCellInfoList(Parcel &p, void *response, size_t responselen)
3254{
3255 if (response == NULL && responselen != 0) {
3256 RLOGE("invalid response: NULL");
3257 return RIL_ERRNO_INVALID_RESPONSE;
3258 }
3259
3260 if (responselen % sizeof(RIL_CellInfo) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08003261 RLOGE("responseCellInfoList: invalid response length %d expected multiple of %d",
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003262 (int)responselen, (int)sizeof(RIL_CellInfo));
3263 return RIL_ERRNO_INVALID_RESPONSE;
3264 }
3265
3266 int num = responselen / sizeof(RIL_CellInfo);
3267 p.writeInt32(num);
3268
3269 RIL_CellInfo *p_cur = (RIL_CellInfo *) response;
3270 startResponse;
3271 int i;
3272 for (i = 0; i < num; i++) {
3273 appendPrintBuf("%s[%d: type=%d,registered=%d,timeStampType=%d,timeStamp=%lld", printBuf, i,
3274 p_cur->cellInfoType, p_cur->registered, p_cur->timeStampType, p_cur->timeStamp);
3275 p.writeInt32((int)p_cur->cellInfoType);
3276 p.writeInt32(p_cur->registered);
3277 p.writeInt32(p_cur->timeStampType);
3278 p.writeInt64(p_cur->timeStamp);
3279 switch(p_cur->cellInfoType) {
3280 case RIL_CELL_INFO_TYPE_GSM: {
3281 appendPrintBuf("%s GSM id: mcc=%d,mnc=%d,lac=%d,cid=%d,", printBuf,
3282 p_cur->CellInfo.gsm.cellIdentityGsm.mcc,
3283 p_cur->CellInfo.gsm.cellIdentityGsm.mnc,
3284 p_cur->CellInfo.gsm.cellIdentityGsm.lac,
3285 p_cur->CellInfo.gsm.cellIdentityGsm.cid);
3286 appendPrintBuf("%s gsmSS: ss=%d,ber=%d],", printBuf,
3287 p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength,
3288 p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
3289
3290 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mcc);
3291 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mnc);
3292 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.lac);
3293 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.cid);
3294 p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength);
3295 p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
3296 break;
3297 }
3298 case RIL_CELL_INFO_TYPE_WCDMA: {
3299 appendPrintBuf("%s WCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,psc=%d,", printBuf,
3300 p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc,
3301 p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc,
3302 p_cur->CellInfo.wcdma.cellIdentityWcdma.lac,
3303 p_cur->CellInfo.wcdma.cellIdentityWcdma.cid,
3304 p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
3305 appendPrintBuf("%s wcdmaSS: ss=%d,ber=%d],", printBuf,
3306 p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength,
3307 p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
3308
3309 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc);
3310 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc);
3311 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.lac);
3312 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.cid);
3313 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
3314 p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength);
3315 p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
3316 break;
3317 }
3318 case RIL_CELL_INFO_TYPE_CDMA: {
3319 appendPrintBuf("%s CDMA id: nId=%d,sId=%d,bsId=%d,long=%d,lat=%d", printBuf,
3320 p_cur->CellInfo.cdma.cellIdentityCdma.networkId,
3321 p_cur->CellInfo.cdma.cellIdentityCdma.systemId,
3322 p_cur->CellInfo.cdma.cellIdentityCdma.basestationId,
3323 p_cur->CellInfo.cdma.cellIdentityCdma.longitude,
3324 p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
3325
3326 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.networkId);
3327 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.systemId);
3328 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.basestationId);
3329 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.longitude);
3330 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
3331
3332 appendPrintBuf("%s cdmaSS: dbm=%d ecio=%d evdoSS: dbm=%d,ecio=%d,snr=%d", printBuf,
3333 p_cur->CellInfo.cdma.signalStrengthCdma.dbm,
3334 p_cur->CellInfo.cdma.signalStrengthCdma.ecio,
3335 p_cur->CellInfo.cdma.signalStrengthEvdo.dbm,
3336 p_cur->CellInfo.cdma.signalStrengthEvdo.ecio,
3337 p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
3338
3339 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.dbm);
3340 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.ecio);
3341 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.dbm);
3342 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.ecio);
3343 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
3344 break;
3345 }
3346 case RIL_CELL_INFO_TYPE_LTE: {
3347 appendPrintBuf("%s LTE id: mcc=%d,mnc=%d,ci=%d,pci=%d,tac=%d", printBuf,
3348 p_cur->CellInfo.lte.cellIdentityLte.mcc,
3349 p_cur->CellInfo.lte.cellIdentityLte.mnc,
3350 p_cur->CellInfo.lte.cellIdentityLte.ci,
3351 p_cur->CellInfo.lte.cellIdentityLte.pci,
3352 p_cur->CellInfo.lte.cellIdentityLte.tac);
3353
3354 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mcc);
3355 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mnc);
3356 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.ci);
3357 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.pci);
3358 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.tac);
3359
3360 appendPrintBuf("%s lteSS: ss=%d,rsrp=%d,rsrq=%d,rssnr=%d,cqi=%d,ta=%d", printBuf,
3361 p_cur->CellInfo.lte.signalStrengthLte.signalStrength,
3362 p_cur->CellInfo.lte.signalStrengthLte.rsrp,
3363 p_cur->CellInfo.lte.signalStrengthLte.rsrq,
3364 p_cur->CellInfo.lte.signalStrengthLte.rssnr,
3365 p_cur->CellInfo.lte.signalStrengthLte.cqi,
3366 p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
3367 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.signalStrength);
3368 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrp);
3369 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrq);
3370 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rssnr);
3371 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.cqi);
3372 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
3373 break;
3374 }
Howard Sue32dbfd2015-01-07 15:55:57 +08003375 case RIL_CELL_INFO_TYPE_TD_SCDMA: {
3376 appendPrintBuf("%s TDSCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,cpid=%d,", printBuf,
3377 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc,
3378 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc,
3379 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac,
3380 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid,
3381 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid);
3382 appendPrintBuf("%s tdscdmaSS: rscp=%d],", printBuf,
3383 p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp);
3384
3385 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc);
3386 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc);
3387 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac);
3388 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid);
3389 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid);
3390 p.writeInt32(p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp);
3391 break;
3392 }
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003393 }
3394 p_cur += 1;
3395 }
3396 removeLastChar;
3397 closeResponse;
3398
3399 return 0;
3400}
3401
Howard Sue32dbfd2015-01-07 15:55:57 +08003402static int responseHardwareConfig(Parcel &p, void *response, size_t responselen)
3403{
3404 if (response == NULL && responselen != 0) {
3405 RLOGE("invalid response: NULL");
3406 return RIL_ERRNO_INVALID_RESPONSE;
3407 }
3408
3409 if (responselen % sizeof(RIL_HardwareConfig) != 0) {
3410 RLOGE("responseHardwareConfig: invalid response length %d expected multiple of %d",
3411 (int)responselen, (int)sizeof(RIL_HardwareConfig));
3412 return RIL_ERRNO_INVALID_RESPONSE;
3413 }
3414
3415 int num = responselen / sizeof(RIL_HardwareConfig);
3416 int i;
3417 RIL_HardwareConfig *p_cur = (RIL_HardwareConfig *) response;
3418
3419 p.writeInt32(num);
3420
3421 startResponse;
3422 for (i = 0; i < num; i++) {
3423 switch (p_cur[i].type) {
3424 case RIL_HARDWARE_CONFIG_MODEM: {
3425 writeStringToParcel(p, p_cur[i].uuid);
3426 p.writeInt32((int)p_cur[i].state);
3427 p.writeInt32(p_cur[i].cfg.modem.rat);
3428 p.writeInt32(p_cur[i].cfg.modem.maxVoice);
3429 p.writeInt32(p_cur[i].cfg.modem.maxData);
3430 p.writeInt32(p_cur[i].cfg.modem.maxStandby);
3431
3432 appendPrintBuf("%s modem: uuid=%s,state=%d,rat=%08x,maxV=%d,maxD=%d,maxS=%d", printBuf,
3433 p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.modem.rat,
3434 p_cur[i].cfg.modem.maxVoice, p_cur[i].cfg.modem.maxData, p_cur[i].cfg.modem.maxStandby);
3435 break;
3436 }
3437 case RIL_HARDWARE_CONFIG_SIM: {
3438 writeStringToParcel(p, p_cur[i].uuid);
3439 p.writeInt32((int)p_cur[i].state);
3440 writeStringToParcel(p, p_cur[i].cfg.sim.modemUuid);
3441
3442 appendPrintBuf("%s sim: uuid=%s,state=%d,modem-uuid=%s", printBuf,
3443 p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.sim.modemUuid);
3444 break;
3445 }
3446 }
3447 }
3448 removeLastChar;
3449 closeResponse;
3450 return 0;
3451}
3452
Howard Subd82ef12015-04-12 10:25:05 +02003453static int responseRadioCapability(Parcel &p, void *response, size_t responselen) {
3454 if (response == NULL) {
3455 RLOGE("invalid response: NULL");
3456 return RIL_ERRNO_INVALID_RESPONSE;
3457 }
3458
3459 if (responselen != sizeof (RIL_RadioCapability) ) {
3460 RLOGE("invalid response length was %d expected %d",
3461 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
3462 return RIL_ERRNO_INVALID_RESPONSE;
3463 }
3464
3465 RIL_RadioCapability *p_cur = (RIL_RadioCapability *) response;
3466 p.writeInt32(p_cur->version);
3467 p.writeInt32(p_cur->session);
3468 p.writeInt32(p_cur->phase);
3469 p.writeInt32(p_cur->rat);
3470 writeStringToParcel(p, p_cur->logicalModemUuid);
3471 p.writeInt32(p_cur->status);
3472
3473 startResponse;
3474 appendPrintBuf("%s[version=%d,session=%d,phase=%d,\
Andreas Schneidera8d09502015-06-23 18:41:38 +02003475 rat=%d,logicalModemUuid=%s,status=%d]",
Howard Subd82ef12015-04-12 10:25:05 +02003476 printBuf,
3477 p_cur->version,
3478 p_cur->session,
3479 p_cur->phase,
3480 p_cur->rat,
3481 p_cur->logicalModemUuid,
3482 p_cur->status);
3483 closeResponse;
3484 return 0;
3485}
3486
3487static int responseSSData(Parcel &p, void *response, size_t responselen) {
3488 RLOGD("In responseSSData");
3489 int num;
3490
3491 if (response == NULL && responselen != 0) {
3492 RLOGE("invalid response length was %d expected %d",
3493 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
3494 return RIL_ERRNO_INVALID_RESPONSE;
3495 }
3496
3497 if (responselen != sizeof(RIL_StkCcUnsolSsResponse)) {
3498 RLOGE("invalid response length %d, expected %d",
3499 (int)responselen, (int)sizeof(RIL_StkCcUnsolSsResponse));
3500 return RIL_ERRNO_INVALID_RESPONSE;
3501 }
3502
3503 startResponse;
3504 RIL_StkCcUnsolSsResponse *p_cur = (RIL_StkCcUnsolSsResponse *) response;
3505 p.writeInt32(p_cur->serviceType);
3506 p.writeInt32(p_cur->requestType);
3507 p.writeInt32(p_cur->teleserviceType);
3508 p.writeInt32(p_cur->serviceClass);
3509 p.writeInt32(p_cur->result);
3510
3511 if (isServiceTypeCfQuery(p_cur->serviceType, p_cur->requestType)) {
3512 RLOGD("responseSSData CF type, num of Cf elements %d", p_cur->cfData.numValidIndexes);
3513 if (p_cur->cfData.numValidIndexes > NUM_SERVICE_CLASSES) {
3514 RLOGE("numValidIndexes is greater than max value %d, "
3515 "truncating it to max value", NUM_SERVICE_CLASSES);
3516 p_cur->cfData.numValidIndexes = NUM_SERVICE_CLASSES;
3517 }
3518 /* number of call info's */
3519 p.writeInt32(p_cur->cfData.numValidIndexes);
3520
3521 for (int i = 0; i < p_cur->cfData.numValidIndexes; i++) {
3522 RIL_CallForwardInfo cf = p_cur->cfData.cfInfo[i];
3523
3524 p.writeInt32(cf.status);
3525 p.writeInt32(cf.reason);
3526 p.writeInt32(cf.serviceClass);
3527 p.writeInt32(cf.toa);
3528 writeStringToParcel(p, cf.number);
3529 p.writeInt32(cf.timeSeconds);
3530 appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
3531 (cf.status==1)?"enable":"disable", cf.reason, cf.serviceClass, cf.toa,
3532 (char*)cf.number, cf.timeSeconds);
3533 RLOGD("Data: %d,reason=%d,cls=%d,toa=%d,num=%s,tout=%d],", cf.status,
3534 cf.reason, cf.serviceClass, cf.toa, (char*)cf.number, cf.timeSeconds);
3535 }
3536 } else {
3537 p.writeInt32 (SS_INFO_MAX);
3538
3539 /* each int*/
3540 for (int i = 0; i < SS_INFO_MAX; i++) {
3541 appendPrintBuf("%s%d,", printBuf, p_cur->ssInfo[i]);
3542 RLOGD("Data: %d",p_cur->ssInfo[i]);
3543 p.writeInt32(p_cur->ssInfo[i]);
3544 }
3545 }
3546 removeLastChar;
3547 closeResponse;
3548
3549 return 0;
3550}
3551
3552static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType) {
3553 if ((reqType == SS_INTERROGATION) &&
3554 (serType == SS_CFU ||
3555 serType == SS_CF_BUSY ||
3556 serType == SS_CF_NO_REPLY ||
3557 serType == SS_CF_NOT_REACHABLE ||
3558 serType == SS_CF_ALL ||
3559 serType == SS_CF_ALL_CONDITIONAL)) {
3560 return true;
3561 }
3562 return false;
3563}
3564
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003565static void triggerEvLoop() {
3566 int ret;
3567 if (!pthread_equal(pthread_self(), s_tid_dispatch)) {
3568 /* trigger event loop to wakeup. No reason to do this,
3569 * if we're in the event loop thread */
3570 do {
3571 ret = write (s_fdWakeupWrite, " ", 1);
3572 } while (ret < 0 && errno == EINTR);
3573 }
3574}
3575
3576static void rilEventAddWakeup(struct ril_event *ev) {
3577 ril_event_add(ev);
3578 triggerEvLoop();
3579}
3580
3581static void sendSimStatusAppInfo(Parcel &p, int num_apps, RIL_AppStatus appStatus[]) {
3582 p.writeInt32(num_apps);
3583 startResponse;
3584 for (int i = 0; i < num_apps; i++) {
3585 p.writeInt32(appStatus[i].app_type);
3586 p.writeInt32(appStatus[i].app_state);
3587 p.writeInt32(appStatus[i].perso_substate);
3588 writeStringToParcel(p, (const char*)(appStatus[i].aid_ptr));
3589 writeStringToParcel(p, (const char*)
3590 (appStatus[i].app_label_ptr));
3591 p.writeInt32(appStatus[i].pin1_replaced);
3592 p.writeInt32(appStatus[i].pin1);
3593 p.writeInt32(appStatus[i].pin2);
3594 appendPrintBuf("%s[app_type=%d,app_state=%d,perso_substate=%d,\
3595 aid_ptr=%s,app_label_ptr=%s,pin1_replaced=%d,pin1=%d,pin2=%d],",
3596 printBuf,
3597 appStatus[i].app_type,
3598 appStatus[i].app_state,
3599 appStatus[i].perso_substate,
3600 appStatus[i].aid_ptr,
3601 appStatus[i].app_label_ptr,
3602 appStatus[i].pin1_replaced,
3603 appStatus[i].pin1,
3604 appStatus[i].pin2);
3605 }
3606 closeResponse;
3607}
3608
3609static int responseSimStatus(Parcel &p, void *response, size_t responselen) {
Howard Sue32dbfd2015-01-07 15:55:57 +08003610 int i;
3611
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003612 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003613 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003614 return RIL_ERRNO_INVALID_RESPONSE;
3615 }
3616
3617 if (responselen == sizeof (RIL_CardStatus_v6)) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003618 RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
3619
3620 p.writeInt32(p_cur->card_state);
3621 p.writeInt32(p_cur->universal_pin_state);
3622 p.writeInt32(p_cur->gsm_umts_subscription_app_index);
3623 p.writeInt32(p_cur->cdma_subscription_app_index);
3624 p.writeInt32(p_cur->ims_subscription_app_index);
3625
3626 sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
3627 } else if (responselen == sizeof (RIL_CardStatus_v5)) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003628 RIL_CardStatus_v5 *p_cur = ((RIL_CardStatus_v5 *) response);
3629
3630 p.writeInt32(p_cur->card_state);
3631 p.writeInt32(p_cur->universal_pin_state);
3632 p.writeInt32(p_cur->gsm_umts_subscription_app_index);
3633 p.writeInt32(p_cur->cdma_subscription_app_index);
3634 p.writeInt32(-1);
3635
3636 sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
3637 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003638 RLOGE("responseSimStatus: A RilCardStatus_v6 or _v5 expected\n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003639 return RIL_ERRNO_INVALID_RESPONSE;
3640 }
3641
3642 return 0;
3643}
3644
3645static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen) {
3646 int num = responselen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *);
3647 p.writeInt32(num);
3648
3649 startResponse;
3650 RIL_GSM_BroadcastSmsConfigInfo **p_cur =
3651 (RIL_GSM_BroadcastSmsConfigInfo **) response;
3652 for (int i = 0; i < num; i++) {
3653 p.writeInt32(p_cur[i]->fromServiceId);
3654 p.writeInt32(p_cur[i]->toServiceId);
3655 p.writeInt32(p_cur[i]->fromCodeScheme);
3656 p.writeInt32(p_cur[i]->toCodeScheme);
3657 p.writeInt32(p_cur[i]->selected);
3658
3659 appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId=%d, \
3660 fromCodeScheme=%d, toCodeScheme=%d, selected =%d]",
3661 printBuf, i, p_cur[i]->fromServiceId, p_cur[i]->toServiceId,
3662 p_cur[i]->fromCodeScheme, p_cur[i]->toCodeScheme,
3663 p_cur[i]->selected);
3664 }
3665 closeResponse;
3666
3667 return 0;
3668}
3669
3670static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen) {
3671 RIL_CDMA_BroadcastSmsConfigInfo **p_cur =
3672 (RIL_CDMA_BroadcastSmsConfigInfo **) response;
3673
3674 int num = responselen / sizeof (RIL_CDMA_BroadcastSmsConfigInfo *);
3675 p.writeInt32(num);
3676
3677 startResponse;
3678 for (int i = 0 ; i < num ; i++ ) {
3679 p.writeInt32(p_cur[i]->service_category);
3680 p.writeInt32(p_cur[i]->language);
3681 p.writeInt32(p_cur[i]->selected);
3682
3683 appendPrintBuf("%s [%d: srvice_category=%d, language =%d, \
3684 selected =%d], ",
3685 printBuf, i, p_cur[i]->service_category, p_cur[i]->language,
3686 p_cur[i]->selected);
3687 }
3688 closeResponse;
3689
3690 return 0;
3691}
3692
3693static int responseCdmaSms(Parcel &p, void *response, size_t responselen) {
3694 int num;
3695 int digitCount;
3696 int digitLimit;
3697 uint8_t uct;
3698 void* dest;
3699
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003700 RLOGD("Inside responseCdmaSms");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003701
3702 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003703 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003704 return RIL_ERRNO_INVALID_RESPONSE;
3705 }
3706
3707 if (responselen != sizeof(RIL_CDMA_SMS_Message)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003708 RLOGE("invalid response length was %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003709 (int)responselen, (int)sizeof(RIL_CDMA_SMS_Message));
3710 return RIL_ERRNO_INVALID_RESPONSE;
3711 }
3712
3713 RIL_CDMA_SMS_Message *p_cur = (RIL_CDMA_SMS_Message *) response;
3714 p.writeInt32(p_cur->uTeleserviceID);
3715 p.write(&(p_cur->bIsServicePresent),sizeof(uct));
3716 p.writeInt32(p_cur->uServicecategory);
3717 p.writeInt32(p_cur->sAddress.digit_mode);
3718 p.writeInt32(p_cur->sAddress.number_mode);
3719 p.writeInt32(p_cur->sAddress.number_type);
3720 p.writeInt32(p_cur->sAddress.number_plan);
3721 p.write(&(p_cur->sAddress.number_of_digits), sizeof(uct));
3722 digitLimit= MIN((p_cur->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
3723 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
3724 p.write(&(p_cur->sAddress.digits[digitCount]),sizeof(uct));
3725 }
3726
3727 p.writeInt32(p_cur->sSubAddress.subaddressType);
3728 p.write(&(p_cur->sSubAddress.odd),sizeof(uct));
3729 p.write(&(p_cur->sSubAddress.number_of_digits),sizeof(uct));
3730 digitLimit= MIN((p_cur->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
3731 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
3732 p.write(&(p_cur->sSubAddress.digits[digitCount]),sizeof(uct));
3733 }
3734
3735 digitLimit= MIN((p_cur->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
3736 p.writeInt32(p_cur->uBearerDataLen);
3737 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
3738 p.write(&(p_cur->aBearerData[digitCount]), sizeof(uct));
3739 }
3740
3741 startResponse;
3742 appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
3743 sAddress.digit_mode=%d, sAddress.number_mode=%d, sAddress.number_type=%d, ",
3744 printBuf, p_cur->uTeleserviceID,p_cur->bIsServicePresent,p_cur->uServicecategory,
3745 p_cur->sAddress.digit_mode, p_cur->sAddress.number_mode,p_cur->sAddress.number_type);
3746 closeResponse;
3747
3748 return 0;
3749}
3750
Howard Sue32dbfd2015-01-07 15:55:57 +08003751static int responseDcRtInfo(Parcel &p, void *response, size_t responselen)
3752{
3753 int num = responselen / sizeof(RIL_DcRtInfo);
3754 if ((responselen % sizeof(RIL_DcRtInfo) != 0) || (num != 1)) {
3755 RLOGE("responseDcRtInfo: invalid response length %d expected multiple of %d",
3756 (int)responselen, (int)sizeof(RIL_DcRtInfo));
3757 return RIL_ERRNO_INVALID_RESPONSE;
3758 }
3759
3760 startResponse;
3761 RIL_DcRtInfo *pDcRtInfo = (RIL_DcRtInfo *)response;
3762 p.writeInt64(pDcRtInfo->time);
3763 p.writeInt32(pDcRtInfo->powerState);
3764 appendPrintBuf("%s[time=%d,powerState=%d]", printBuf,
3765 pDcRtInfo->time,
Andreas Schneidera8d09502015-06-23 18:41:38 +02003766 (int)pDcRtInfo->powerState);
Howard Sue32dbfd2015-01-07 15:55:57 +08003767 closeResponse;
3768
3769 return 0;
3770}
3771
fenglu9bdede02015-04-14 14:53:55 -07003772static int responseLceStatus(Parcel &p, void *response, size_t responselen) {
3773 if (response == NULL || responselen != sizeof(RIL_LceStatusInfo)) {
3774 if (response == NULL) {
3775 RLOGE("invalid response: NULL");
3776 }
3777 else {
3778 RLOGE("responseLceStatus: invalid response length %d expecting len: d%",
3779 sizeof(RIL_LceStatusInfo), responselen);
3780 }
3781 return RIL_ERRNO_INVALID_RESPONSE;
3782 }
3783
3784 RIL_LceStatusInfo *p_cur = (RIL_LceStatusInfo *)response;
3785 p.write((void *)p_cur, 1); // p_cur->lce_status takes one byte.
3786 p.writeInt32(p_cur->actual_interval_ms);
3787
3788 startResponse;
3789 appendPrintBuf("LCE Status: %d, actual_interval_ms: %d",
3790 p_cur->lce_status, p_cur->actual_interval_ms);
3791 closeResponse;
3792
3793 return 0;
3794}
3795
3796static int responseLceData(Parcel &p, void *response, size_t responselen) {
3797 if (response == NULL || responselen != sizeof(RIL_LceDataInfo)) {
3798 if (response == NULL) {
3799 RLOGE("invalid response: NULL");
3800 }
3801 else {
3802 RLOGE("responseLceData: invalid response length %d expecting len: d%",
3803 sizeof(RIL_LceDataInfo), responselen);
3804 }
3805 return RIL_ERRNO_INVALID_RESPONSE;
3806 }
3807
3808 RIL_LceDataInfo *p_cur = (RIL_LceDataInfo *)response;
3809 p.writeInt32(p_cur->last_hop_capacity_kbps);
3810
3811 /* p_cur->confidence_level and p_cur->lce_suspended take 1 byte each.*/
3812 p.write((void *)&(p_cur->confidence_level), 1);
3813 p.write((void *)&(p_cur->lce_suspended), 1);
3814
3815 startResponse;
forkbombe0568e12015-11-23 18:37:37 +11003816 appendPrintBuf("LCE info received: capacity %d confidence level %d"
3817 "and suspended %d",
fenglu9bdede02015-04-14 14:53:55 -07003818 p_cur->last_hop_capacity_kbps, p_cur->confidence_level,
3819 p_cur->lce_suspended);
3820 closeResponse;
3821
3822 return 0;
3823}
3824
Prerepa Viswanadham8e755592015-05-28 00:37:32 -07003825static int responseActivityData(Parcel &p, void *response, size_t responselen) {
3826 if (response == NULL || responselen != sizeof(RIL_ActivityStatsInfo)) {
3827 if (response == NULL) {
3828 RLOGE("invalid response: NULL");
3829 }
3830 else {
3831 RLOGE("responseActivityData: invalid response length %d expecting len: d%",
3832 sizeof(RIL_ActivityStatsInfo), responselen);
3833 }
3834 return RIL_ERRNO_INVALID_RESPONSE;
3835 }
3836
3837 RIL_ActivityStatsInfo *p_cur = (RIL_ActivityStatsInfo *)response;
3838 p.writeInt32(p_cur->sleep_mode_time_ms);
3839 p.writeInt32(p_cur->idle_mode_time_ms);
3840 for(int i = 0; i < RIL_NUM_TX_POWER_LEVELS; i++) {
3841 p.writeInt32(p_cur->tx_mode_time_ms[i]);
3842 }
3843 p.writeInt32(p_cur->rx_mode_time_ms);
3844
3845 startResponse;
forkbombe0568e12015-11-23 18:37:37 +11003846 appendPrintBuf("Modem activity info received: sleep_mode_time_ms %d idle_mode_time_ms %d"
3847 "tx_mode_time_ms %d %d %d %d %d and rx_mode_time_ms %d",
Prerepa Viswanadham8e755592015-05-28 00:37:32 -07003848 p_cur->sleep_mode_time_ms, p_cur->idle_mode_time_ms, p_cur->tx_mode_time_ms[0],
3849 p_cur->tx_mode_time_ms[1], p_cur->tx_mode_time_ms[2], p_cur->tx_mode_time_ms[3],
3850 p_cur->tx_mode_time_ms[4], p_cur->rx_mode_time_ms);
3851 closeResponse;
3852
3853 return 0;
3854}
3855
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003856/**
3857 * A write on the wakeup fd is done just to pop us out of select()
3858 * We empty the buffer here and then ril_event will reset the timers on the
3859 * way back down
3860 */
3861static void processWakeupCallback(int fd, short flags, void *param) {
3862 char buff[16];
3863 int ret;
3864
Ethan Chend6e30652013-08-04 22:49:56 -07003865 RLOGV("processWakeupCallback");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003866
3867 /* empty our wakeup socket out */
3868 do {
3869 ret = read(s_fdWakeupRead, &buff, sizeof(buff));
3870 } while (ret > 0 || (ret < 0 && errno == EINTR));
3871}
3872
Howard Sue32dbfd2015-01-07 15:55:57 +08003873static void onCommandsSocketClosed(RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003874 int ret;
3875 RequestInfo *p_cur;
Howard Sue32dbfd2015-01-07 15:55:57 +08003876 /* Hook for current context
3877 pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
3878 pthread_mutex_t * pendingRequestsMutexHook = &s_pendingRequestsMutex;
3879 /* pendingRequestsHook refer to &s_pendingRequests */
3880 RequestInfo ** pendingRequestsHook = &s_pendingRequests;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003881
Howard Sue32dbfd2015-01-07 15:55:57 +08003882#if (SIM_COUNT >= 2)
3883 if (socket_id == RIL_SOCKET_2) {
3884 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
3885 pendingRequestsHook = &s_pendingRequests_socket2;
3886 }
3887#if (SIM_COUNT >= 3)
3888 else if (socket_id == RIL_SOCKET_3) {
3889 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
3890 pendingRequestsHook = &s_pendingRequests_socket3;
3891 }
3892#endif
3893#if (SIM_COUNT >= 4)
3894 else if (socket_id == RIL_SOCKET_4) {
3895 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
3896 pendingRequestsHook = &s_pendingRequests_socket4;
3897 }
3898#endif
3899#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003900 /* mark pending requests as "cancelled" so we dont report responses */
Howard Sue32dbfd2015-01-07 15:55:57 +08003901 ret = pthread_mutex_lock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003902 assert (ret == 0);
3903
Howard Sue32dbfd2015-01-07 15:55:57 +08003904 p_cur = *pendingRequestsHook;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003905
Howard Sue32dbfd2015-01-07 15:55:57 +08003906 for (p_cur = *pendingRequestsHook
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003907 ; p_cur != NULL
3908 ; p_cur = p_cur->p_next
3909 ) {
3910 p_cur->cancelled = 1;
3911 }
3912
Howard Sue32dbfd2015-01-07 15:55:57 +08003913 ret = pthread_mutex_unlock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003914 assert (ret == 0);
3915}
3916
3917static void processCommandsCallback(int fd, short flags, void *param) {
3918 RecordStream *p_rs;
3919 void *p_record;
3920 size_t recordlen;
3921 int ret;
Howard Sue32dbfd2015-01-07 15:55:57 +08003922 SocketListenParam *p_info = (SocketListenParam *)param;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003923
Howard Sue32dbfd2015-01-07 15:55:57 +08003924 assert(fd == p_info->fdCommand);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003925
Howard Sue32dbfd2015-01-07 15:55:57 +08003926 p_rs = p_info->p_rs;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003927
3928 for (;;) {
3929 /* loop until EAGAIN/EINTR, end of stream, or other error */
3930 ret = record_stream_get_next(p_rs, &p_record, &recordlen);
3931
3932 if (ret == 0 && p_record == NULL) {
3933 /* end-of-stream */
3934 break;
3935 } else if (ret < 0) {
3936 break;
3937 } else if (ret == 0) { /* && p_record != NULL */
Howard Sue32dbfd2015-01-07 15:55:57 +08003938 processCommandBuffer(p_record, recordlen, p_info->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003939 }
3940 }
3941
3942 if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) {
3943 /* fatal error or end-of-stream */
3944 if (ret != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003945 RLOGE("error on reading command socket errno:%d\n", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003946 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003947 RLOGW("EOS. Closing command socket.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003948 }
3949
Howard Sue32dbfd2015-01-07 15:55:57 +08003950 close(fd);
3951 p_info->fdCommand = -1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003952
Howard Sue32dbfd2015-01-07 15:55:57 +08003953 ril_event_del(p_info->commands_event);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003954
3955 record_stream_free(p_rs);
3956
3957 /* start listening for new connections again */
3958 rilEventAddWakeup(&s_listen_event);
3959
Howard Sue32dbfd2015-01-07 15:55:57 +08003960 onCommandsSocketClosed(p_info->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003961 }
3962}
3963
Howard Subd82ef12015-04-12 10:25:05 +02003964
Howard Sue32dbfd2015-01-07 15:55:57 +08003965static void onNewCommandConnect(RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003966 // Inform we are connected and the ril version
3967 int rilVer = s_callbacks.version;
Howard Sue32dbfd2015-01-07 15:55:57 +08003968 RIL_UNSOL_RESPONSE(RIL_UNSOL_RIL_CONNECTED,
3969 &rilVer, sizeof(rilVer), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003970
3971 // implicit radio state changed
Howard Sue32dbfd2015-01-07 15:55:57 +08003972 RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
3973 NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003974
3975 // Send last NITZ time data, in case it was missed
3976 if (s_lastNITZTimeData != NULL) {
Howard Sue32dbfd2015-01-07 15:55:57 +08003977 sendResponseRaw(s_lastNITZTimeData, s_lastNITZTimeDataSize, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003978
3979 free(s_lastNITZTimeData);
3980 s_lastNITZTimeData = NULL;
3981 }
3982
3983 // Get version string
3984 if (s_callbacks.getVersion != NULL) {
3985 const char *version;
3986 version = s_callbacks.getVersion();
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003987 RLOGI("RIL Daemon version: %s\n", version);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003988
3989 property_set(PROPERTY_RIL_IMPL, version);
3990 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003991 RLOGI("RIL Daemon version: unavailable\n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003992 property_set(PROPERTY_RIL_IMPL, "unavailable");
3993 }
3994
3995}
3996
3997static void listenCallback (int fd, short flags, void *param) {
3998 int ret;
3999 int err;
4000 int is_phone_socket;
Howard Sue32dbfd2015-01-07 15:55:57 +08004001 int fdCommand = -1;
Dheeraj Shettycc231012014-07-02 21:27:57 +02004002 char* processName;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004003 RecordStream *p_rs;
Dheeraj Shettycc231012014-07-02 21:27:57 +02004004 MySocketListenParam* listenParam;
4005 RilSocket *sapSocket = NULL;
4006 socketClient *sClient = NULL;
4007
Howard Sue32dbfd2015-01-07 15:55:57 +08004008 SocketListenParam *p_info = (SocketListenParam *)param;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004009
Dheeraj Shettycc231012014-07-02 21:27:57 +02004010 if(RIL_SAP_SOCKET == p_info->type) {
4011 listenParam = (MySocketListenParam *)param;
4012 sapSocket = listenParam->socket;
4013 }
4014
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004015 struct sockaddr_un peeraddr;
4016 socklen_t socklen = sizeof (peeraddr);
4017
4018 struct ucred creds;
4019 socklen_t szCreds = sizeof(creds);
4020
4021 struct passwd *pwd = NULL;
4022
Dheeraj Shettycc231012014-07-02 21:27:57 +02004023 if(NULL == sapSocket) {
4024 assert (*p_info->fdCommand < 0);
4025 assert (fd == *p_info->fdListen);
4026 processName = PHONE_PROCESS;
4027 } else {
4028 assert (sapSocket->commandFd < 0);
4029 assert (fd == sapSocket->listenFd);
4030 processName = BLUETOOTH_PROCESS;
4031 }
4032
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004033
Howard Sue32dbfd2015-01-07 15:55:57 +08004034 fdCommand = accept(fd, (sockaddr *) &peeraddr, &socklen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004035
Howard Sue32dbfd2015-01-07 15:55:57 +08004036 if (fdCommand < 0 ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004037 RLOGE("Error on accept() errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004038 /* start listening for new connections again */
Dheeraj Shettycc231012014-07-02 21:27:57 +02004039 if(NULL == sapSocket) {
4040 rilEventAddWakeup(p_info->listen_event);
4041 } else {
4042 rilEventAddWakeup(sapSocket->getListenEvent());
4043 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004044 return;
4045 }
4046
4047 /* check the credential of the other side and only accept socket from
4048 * phone process
4049 */
4050 errno = 0;
4051 is_phone_socket = 0;
4052
Howard Sue32dbfd2015-01-07 15:55:57 +08004053 err = getsockopt(fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004054
4055 if (err == 0 && szCreds > 0) {
4056 errno = 0;
4057 pwd = getpwuid(creds.uid);
4058 if (pwd != NULL) {
Dheeraj Shettycc231012014-07-02 21:27:57 +02004059 if (strcmp(pwd->pw_name, processName) == 0) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004060 is_phone_socket = 1;
4061 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004062 RLOGE("RILD can't accept socket from process %s", pwd->pw_name);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004063 }
4064 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004065 RLOGE("Error on getpwuid() errno: %d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004066 }
4067 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004068 RLOGD("Error on getsockopt() errno: %d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004069 }
4070
Howard Subd82ef12015-04-12 10:25:05 +02004071 if (!is_phone_socket) {
Dheeraj Shettycc231012014-07-02 21:27:57 +02004072 RLOGE("RILD must accept socket from %s", processName);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004073
Dheeraj Shettycc231012014-07-02 21:27:57 +02004074 close(fdCommand);
4075 fdCommand = -1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004076
Dheeraj Shettycc231012014-07-02 21:27:57 +02004077 if(NULL == sapSocket) {
4078 onCommandsSocketClosed(p_info->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004079
Dheeraj Shettycc231012014-07-02 21:27:57 +02004080 /* start listening for new connections again */
4081 rilEventAddWakeup(p_info->listen_event);
4082 } else {
4083 sapSocket->onCommandsSocketClosed();
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004084
Dheeraj Shettycc231012014-07-02 21:27:57 +02004085 /* start listening for new connections again */
4086 rilEventAddWakeup(sapSocket->getListenEvent());
4087 }
4088
4089 return;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004090 }
4091
Howard Sue32dbfd2015-01-07 15:55:57 +08004092 ret = fcntl(fdCommand, F_SETFL, O_NONBLOCK);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004093
4094 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004095 RLOGE ("Error setting O_NONBLOCK errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004096 }
4097
Dheeraj Shettycc231012014-07-02 21:27:57 +02004098 if(NULL == sapSocket) {
4099 RLOGI("libril: new connection to %s", rilSocketIdToString(p_info->socket_id));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004100
Dheeraj Shettycc231012014-07-02 21:27:57 +02004101 p_info->fdCommand = fdCommand;
4102 p_rs = record_stream_new(p_info->fdCommand, MAX_COMMAND_BYTES);
4103 p_info->p_rs = p_rs;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004104
Dheeraj Shettycc231012014-07-02 21:27:57 +02004105 ril_event_set (p_info->commands_event, p_info->fdCommand, 1,
Howard Sue32dbfd2015-01-07 15:55:57 +08004106 p_info->processCommandsCallback, p_info);
Dheeraj Shettycc231012014-07-02 21:27:57 +02004107 rilEventAddWakeup (p_info->commands_event);
Howard Sue32dbfd2015-01-07 15:55:57 +08004108
Dheeraj Shettycc231012014-07-02 21:27:57 +02004109 onNewCommandConnect(p_info->socket_id);
4110 } else {
4111 RLOGI("libril: new connection");
Howard Sue32dbfd2015-01-07 15:55:57 +08004112
Dheeraj Shettycc231012014-07-02 21:27:57 +02004113 sapSocket->setCommandFd(fdCommand);
4114 p_rs = record_stream_new(sapSocket->getCommandFd(), MAX_COMMAND_BYTES);
4115 sClient = new socketClient(sapSocket,p_rs);
4116 ril_event_set (sapSocket->getCallbackEvent(), sapSocket->getCommandFd(), 1,
4117 sapSocket->getCommandCb(), sClient);
4118
4119 rilEventAddWakeup(sapSocket->getCallbackEvent());
4120 sapSocket->onNewCommandConnect();
4121 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004122}
4123
4124static void freeDebugCallbackArgs(int number, char **args) {
4125 for (int i = 0; i < number; i++) {
4126 if (args[i] != NULL) {
4127 free(args[i]);
4128 }
4129 }
4130 free(args);
4131}
4132
4133static void debugCallback (int fd, short flags, void *param) {
4134 int acceptFD, option;
4135 struct sockaddr_un peeraddr;
4136 socklen_t socklen = sizeof (peeraddr);
4137 int data;
4138 unsigned int qxdm_data[6];
4139 const char *deactData[1] = {"1"};
4140 char *actData[1];
4141 RIL_Dial dialData;
4142 int hangupData[1] = {1};
4143 int number;
4144 char **args;
Howard Sue32dbfd2015-01-07 15:55:57 +08004145 RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
4146 int sim_id = 0;
4147
4148 RLOGI("debugCallback for socket %s", rilSocketIdToString(socket_id));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004149
4150 acceptFD = accept (fd, (sockaddr *) &peeraddr, &socklen);
4151
4152 if (acceptFD < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004153 RLOGE ("error accepting on debug port: %d\n", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004154 return;
4155 }
4156
4157 if (recv(acceptFD, &number, sizeof(int), 0) != sizeof(int)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004158 RLOGE ("error reading on socket: number of Args: \n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004159 return;
4160 }
4161 args = (char **) malloc(sizeof(char*) * number);
4162
4163 for (int i = 0; i < number; i++) {
4164 int len;
4165 if (recv(acceptFD, &len, sizeof(int), 0) != sizeof(int)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004166 RLOGE ("error reading on socket: Len of Args: \n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004167 freeDebugCallbackArgs(i, args);
4168 return;
4169 }
4170 // +1 for null-term
4171 args[i] = (char *) malloc((sizeof(char) * len) + 1);
4172 if (recv(acceptFD, args[i], sizeof(char) * len, 0)
4173 != (int)sizeof(char) * len) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004174 RLOGE ("error reading on socket: Args[%d] \n", i);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004175 freeDebugCallbackArgs(i, args);
4176 return;
4177 }
4178 char * buf = args[i];
4179 buf[len] = 0;
Howard Sue32dbfd2015-01-07 15:55:57 +08004180 if ((i+1) == number) {
4181 /* The last argument should be sim id 0(SIM1)~3(SIM4) */
4182 sim_id = atoi(args[i]);
4183 switch (sim_id) {
4184 case 0:
4185 socket_id = RIL_SOCKET_1;
4186 break;
4187 #if (SIM_COUNT >= 2)
4188 case 1:
4189 socket_id = RIL_SOCKET_2;
4190 break;
4191 #endif
4192 #if (SIM_COUNT >= 3)
4193 case 2:
4194 socket_id = RIL_SOCKET_3;
4195 break;
4196 #endif
4197 #if (SIM_COUNT >= 4)
4198 case 3:
4199 socket_id = RIL_SOCKET_4;
4200 break;
4201 #endif
4202 default:
4203 socket_id = RIL_SOCKET_1;
4204 break;
4205 }
4206 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004207 }
4208
4209 switch (atoi(args[0])) {
4210 case 0:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004211 RLOGI ("Connection on debug port: issuing reset.");
Howard Sue32dbfd2015-01-07 15:55:57 +08004212 issueLocalRequest(RIL_REQUEST_RESET_RADIO, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004213 break;
4214 case 1:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004215 RLOGI ("Connection on debug port: issuing radio power off.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004216 data = 0;
Howard Sue32dbfd2015-01-07 15:55:57 +08004217 issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004218 // Close the socket
Howard Subd82ef12015-04-12 10:25:05 +02004219 if (socket_id == RIL_SOCKET_1 && s_ril_param_socket.fdCommand > 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004220 close(s_ril_param_socket.fdCommand);
4221 s_ril_param_socket.fdCommand = -1;
4222 }
4223 #if (SIM_COUNT == 2)
4224 else if (socket_id == RIL_SOCKET_2 && s_ril_param_socket2.fdCommand > 0) {
4225 close(s_ril_param_socket2.fdCommand);
4226 s_ril_param_socket2.fdCommand = -1;
4227 }
4228 #endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004229 break;
4230 case 2:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004231 RLOGI ("Debug port: issuing unsolicited voice network change.");
Howard Sue32dbfd2015-01-07 15:55:57 +08004232 RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004233 break;
4234 case 3:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004235 RLOGI ("Debug port: QXDM log enable.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004236 qxdm_data[0] = 65536; // head.func_tag
4237 qxdm_data[1] = 16; // head.len
4238 qxdm_data[2] = 1; // mode: 1 for 'start logging'
4239 qxdm_data[3] = 32; // log_file_size: 32megabytes
4240 qxdm_data[4] = 0; // log_mask
4241 qxdm_data[5] = 8; // log_max_fileindex
4242 issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
Howard Sue32dbfd2015-01-07 15:55:57 +08004243 6 * sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004244 break;
4245 case 4:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004246 RLOGI ("Debug port: QXDM log disable.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004247 qxdm_data[0] = 65536;
4248 qxdm_data[1] = 16;
4249 qxdm_data[2] = 0; // mode: 0 for 'stop logging'
4250 qxdm_data[3] = 32;
4251 qxdm_data[4] = 0;
4252 qxdm_data[5] = 8;
4253 issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
Howard Sue32dbfd2015-01-07 15:55:57 +08004254 6 * sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004255 break;
4256 case 5:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004257 RLOGI("Debug port: Radio On");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004258 data = 1;
Howard Sue32dbfd2015-01-07 15:55:57 +08004259 issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004260 sleep(2);
4261 // Set network selection automatic.
Howard Sue32dbfd2015-01-07 15:55:57 +08004262 issueLocalRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004263 break;
4264 case 6:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004265 RLOGI("Debug port: Setup Data Call, Apn :%s\n", args[1]);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004266 actData[0] = args[1];
4267 issueLocalRequest(RIL_REQUEST_SETUP_DATA_CALL, &actData,
Howard Sue32dbfd2015-01-07 15:55:57 +08004268 sizeof(actData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004269 break;
4270 case 7:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004271 RLOGI("Debug port: Deactivate Data Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004272 issueLocalRequest(RIL_REQUEST_DEACTIVATE_DATA_CALL, &deactData,
Howard Sue32dbfd2015-01-07 15:55:57 +08004273 sizeof(deactData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004274 break;
4275 case 8:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004276 RLOGI("Debug port: Dial Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004277 dialData.clir = 0;
4278 dialData.address = args[1];
Howard Sue32dbfd2015-01-07 15:55:57 +08004279 issueLocalRequest(RIL_REQUEST_DIAL, &dialData, sizeof(dialData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004280 break;
4281 case 9:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004282 RLOGI("Debug port: Answer Call");
Howard Sue32dbfd2015-01-07 15:55:57 +08004283 issueLocalRequest(RIL_REQUEST_ANSWER, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004284 break;
4285 case 10:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004286 RLOGI("Debug port: End Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004287 issueLocalRequest(RIL_REQUEST_HANGUP, &hangupData,
Howard Sue32dbfd2015-01-07 15:55:57 +08004288 sizeof(hangupData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004289 break;
4290 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004291 RLOGE ("Invalid request");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004292 break;
4293 }
4294 freeDebugCallbackArgs(number, args);
4295 close(acceptFD);
4296}
4297
4298
4299static void userTimerCallback (int fd, short flags, void *param) {
4300 UserCallbackInfo *p_info;
4301
4302 p_info = (UserCallbackInfo *)param;
4303
4304 p_info->p_callback(p_info->userParam);
4305
4306
4307 // FIXME generalize this...there should be a cancel mechanism
4308 if (s_last_wake_timeout_info != NULL && s_last_wake_timeout_info == p_info) {
4309 s_last_wake_timeout_info = NULL;
4310 }
4311
4312 free(p_info);
4313}
4314
4315
4316static void *
4317eventLoop(void *param) {
4318 int ret;
4319 int filedes[2];
4320
4321 ril_event_init();
4322
4323 pthread_mutex_lock(&s_startupMutex);
4324
4325 s_started = 1;
4326 pthread_cond_broadcast(&s_startupCond);
4327
4328 pthread_mutex_unlock(&s_startupMutex);
4329
4330 ret = pipe(filedes);
4331
4332 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004333 RLOGE("Error in pipe() errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004334 return NULL;
4335 }
4336
4337 s_fdWakeupRead = filedes[0];
4338 s_fdWakeupWrite = filedes[1];
4339
4340 fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
4341
4342 ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
4343 processWakeupCallback, NULL);
4344
4345 rilEventAddWakeup (&s_wakeupfd_event);
4346
4347 // Only returns on error
4348 ril_event_loop();
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004349 RLOGE ("error in event_loop_base errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004350 // kill self to restart on error
4351 kill(0, SIGKILL);
4352
4353 return NULL;
4354}
4355
4356extern "C" void
4357RIL_startEventLoop(void) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004358 /* spin up eventLoop thread and wait for it to get started */
4359 s_started = 0;
4360 pthread_mutex_lock(&s_startupMutex);
4361
Howard Sue32dbfd2015-01-07 15:55:57 +08004362 pthread_attr_t attr;
4363 pthread_attr_init(&attr);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004364 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
Howard Sue32dbfd2015-01-07 15:55:57 +08004365
4366 int result = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
4367 if (result != 0) {
4368 RLOGE("Failed to create dispatch thread: %s", strerror(result));
4369 goto done;
4370 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004371
4372 while (s_started == 0) {
4373 pthread_cond_wait(&s_startupCond, &s_startupMutex);
4374 }
4375
Howard Sue32dbfd2015-01-07 15:55:57 +08004376done:
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004377 pthread_mutex_unlock(&s_startupMutex);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004378}
4379
4380// Used for testing purpose only.
4381extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) {
4382 memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
4383}
4384
Howard Sue32dbfd2015-01-07 15:55:57 +08004385static void startListen(RIL_SOCKET_ID socket_id, SocketListenParam* socket_listen_p) {
4386 int fdListen = -1;
4387 int ret;
4388 char socket_name[10];
4389
4390 memset(socket_name, 0, sizeof(char)*10);
4391
4392 switch(socket_id) {
4393 case RIL_SOCKET_1:
4394 strncpy(socket_name, RIL_getRilSocketName(), 9);
4395 break;
4396 #if (SIM_COUNT >= 2)
4397 case RIL_SOCKET_2:
4398 strncpy(socket_name, SOCKET2_NAME_RIL, 9);
4399 break;
4400 #endif
4401 #if (SIM_COUNT >= 3)
4402 case RIL_SOCKET_3:
4403 strncpy(socket_name, SOCKET3_NAME_RIL, 9);
4404 break;
4405 #endif
4406 #if (SIM_COUNT >= 4)
4407 case RIL_SOCKET_4:
4408 strncpy(socket_name, SOCKET4_NAME_RIL, 9);
4409 break;
4410 #endif
4411 default:
4412 RLOGE("Socket id is wrong!!");
4413 return;
4414 }
4415
4416 RLOGI("Start to listen %s", rilSocketIdToString(socket_id));
4417
4418 fdListen = android_get_control_socket(socket_name);
4419 if (fdListen < 0) {
4420 RLOGE("Failed to get socket %s", socket_name);
4421 exit(-1);
4422 }
4423
4424 ret = listen(fdListen, 4);
4425
4426 if (ret < 0) {
4427 RLOGE("Failed to listen on control socket '%d': %s",
4428 fdListen, strerror(errno));
4429 exit(-1);
4430 }
4431 socket_listen_p->fdListen = fdListen;
4432
4433 /* note: non-persistent so we can accept only one connection at a time */
4434 ril_event_set (socket_listen_p->listen_event, fdListen, false,
4435 listenCallback, socket_listen_p);
4436
4437 rilEventAddWakeup (socket_listen_p->listen_event);
4438}
4439
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004440extern "C" void
4441RIL_register (const RIL_RadioFunctions *callbacks) {
4442 int ret;
4443 int flags;
4444
Howard Sue32dbfd2015-01-07 15:55:57 +08004445 RLOGI("SIM_COUNT: %d", SIM_COUNT);
4446
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004447 if (callbacks == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004448 RLOGE("RIL_register: RIL_RadioFunctions * null");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004449 return;
4450 }
4451 if (callbacks->version < RIL_VERSION_MIN) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004452 RLOGE("RIL_register: version %d is to old, min version is %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004453 callbacks->version, RIL_VERSION_MIN);
4454 return;
4455 }
4456 if (callbacks->version > RIL_VERSION) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004457 RLOGE("RIL_register: version %d is too new, max version is %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004458 callbacks->version, RIL_VERSION);
4459 return;
4460 }
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004461 RLOGE("RIL_register: RIL version %d", callbacks->version);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004462
4463 if (s_registerCalled > 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004464 RLOGE("RIL_register has been called more than once. "
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004465 "Subsequent call ignored");
4466 return;
4467 }
4468
4469 memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
4470
Howard Sue32dbfd2015-01-07 15:55:57 +08004471 /* Initialize socket1 parameters */
4472 s_ril_param_socket = {
4473 RIL_SOCKET_1, /* socket_id */
4474 -1, /* fdListen */
4475 -1, /* fdCommand */
4476 PHONE_PROCESS, /* processName */
4477 &s_commands_event, /* commands_event */
4478 &s_listen_event, /* listen_event */
4479 processCommandsCallback, /* processCommandsCallback */
4480 NULL /* p_rs */
4481 };
4482
4483#if (SIM_COUNT >= 2)
4484 s_ril_param_socket2 = {
4485 RIL_SOCKET_2, /* socket_id */
4486 -1, /* fdListen */
4487 -1, /* fdCommand */
4488 PHONE_PROCESS, /* processName */
4489 &s_commands_event_socket2, /* commands_event */
4490 &s_listen_event_socket2, /* listen_event */
4491 processCommandsCallback, /* processCommandsCallback */
4492 NULL /* p_rs */
4493 };
4494#endif
4495
4496#if (SIM_COUNT >= 3)
4497 s_ril_param_socket3 = {
4498 RIL_SOCKET_3, /* socket_id */
4499 -1, /* fdListen */
4500 -1, /* fdCommand */
4501 PHONE_PROCESS, /* processName */
4502 &s_commands_event_socket3, /* commands_event */
4503 &s_listen_event_socket3, /* listen_event */
4504 processCommandsCallback, /* processCommandsCallback */
4505 NULL /* p_rs */
4506 };
4507#endif
4508
4509#if (SIM_COUNT >= 4)
4510 s_ril_param_socket4 = {
4511 RIL_SOCKET_4, /* socket_id */
4512 -1, /* fdListen */
4513 -1, /* fdCommand */
4514 PHONE_PROCESS, /* processName */
4515 &s_commands_event_socket4, /* commands_event */
4516 &s_listen_event_socket4, /* listen_event */
4517 processCommandsCallback, /* processCommandsCallback */
4518 NULL /* p_rs */
4519 };
4520#endif
4521
Howard Subd82ef12015-04-12 10:25:05 +02004522
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004523 s_registerCalled = 1;
4524
Howard Sue32dbfd2015-01-07 15:55:57 +08004525 RLOGI("s_registerCalled flag set, %d", s_started);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004526 // Little self-check
4527
4528 for (int i = 0; i < (int)NUM_ELEMS(s_commands); i++) {
4529 assert(i == s_commands[i].requestNumber);
4530 }
4531
Howard Subd82ef12015-04-12 10:25:05 +02004532 for (int i = 0; i < (int)NUM_ELEMS(s_commands_v); i++) {
4533 assert(i + RIL_VENDOR_COMMANDS_OFFSET == s_commands[i].requestNumber);
4534 }
4535
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004536 for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses); i++) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004537 assert(i + RIL_UNSOL_RESPONSE_BASE
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004538 == s_unsolResponses[i].requestNumber);
4539 }
4540
Howard Subd82ef12015-04-12 10:25:05 +02004541 for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses_v); i++) {
4542 assert(i + RIL_UNSOL_RESPONSE_BASE + RIL_VENDOR_COMMANDS_OFFSET
4543 == s_unsolResponses[i].requestNumber);
4544 }
4545
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004546 // New rild impl calls RIL_startEventLoop() first
4547 // old standalone impl wants it here.
4548
4549 if (s_started == 0) {
4550 RIL_startEventLoop();
4551 }
4552
Howard Sue32dbfd2015-01-07 15:55:57 +08004553 // start listen socket1
4554 startListen(RIL_SOCKET_1, &s_ril_param_socket);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004555
Howard Sue32dbfd2015-01-07 15:55:57 +08004556#if (SIM_COUNT >= 2)
4557 // start listen socket2
4558 startListen(RIL_SOCKET_2, &s_ril_param_socket2);
4559#endif /* (SIM_COUNT == 2) */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004560
Howard Sue32dbfd2015-01-07 15:55:57 +08004561#if (SIM_COUNT >= 3)
4562 // start listen socket3
4563 startListen(RIL_SOCKET_3, &s_ril_param_socket3);
4564#endif /* (SIM_COUNT == 3) */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004565
Howard Sue32dbfd2015-01-07 15:55:57 +08004566#if (SIM_COUNT >= 4)
4567 // start listen socket4
4568 startListen(RIL_SOCKET_4, &s_ril_param_socket4);
4569#endif /* (SIM_COUNT == 4) */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004570
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004571
4572#if 1
4573 // start debug interface socket
4574
Howard Sue32dbfd2015-01-07 15:55:57 +08004575 char *inst = NULL;
4576 if (strlen(RIL_getRilSocketName()) >= strlen(SOCKET_NAME_RIL)) {
4577 inst = RIL_getRilSocketName() + strlen(SOCKET_NAME_RIL);
4578 }
4579
4580 char rildebug[MAX_DEBUG_SOCKET_NAME_LENGTH] = SOCKET_NAME_RIL_DEBUG;
4581 if (inst != NULL) {
Andreas Schneider3063dc12015-04-13 23:04:05 +02004582 snprintf(rildebug, sizeof(rildebug), "%s%s", SOCKET_NAME_RIL_DEBUG, inst);
Howard Sue32dbfd2015-01-07 15:55:57 +08004583 }
4584
4585 s_fdDebug = android_get_control_socket(rildebug);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004586 if (s_fdDebug < 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004587 RLOGE("Failed to get socket : %s errno:%d", rildebug, errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004588 exit(-1);
4589 }
4590
4591 ret = listen(s_fdDebug, 4);
4592
4593 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004594 RLOGE("Failed to listen on ril debug socket '%d': %s",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004595 s_fdDebug, strerror(errno));
4596 exit(-1);
4597 }
4598
4599 ril_event_set (&s_debug_event, s_fdDebug, true,
4600 debugCallback, NULL);
4601
4602 rilEventAddWakeup (&s_debug_event);
4603#endif
4604
4605}
4606
Dheeraj Shettycc231012014-07-02 21:27:57 +02004607extern "C" void
4608RIL_register_socket (RIL_RadioFunctions *(*Init)(const struct RIL_Env *, int, char **),RIL_SOCKET_TYPE socketType, int argc, char **argv) {
4609
4610 RIL_RadioFunctions* UimFuncs = NULL;
4611
4612 if(Init) {
4613 UimFuncs = Init(&RilSapSocket::uimRilEnv, argc, argv);
4614
4615 switch(socketType) {
4616 case RIL_SAP_SOCKET:
4617 RilSapSocket::initSapSocket("sap_uim_socket1", UimFuncs);
4618
4619#if (SIM_COUNT >= 2)
4620 RilSapSocket::initSapSocket("sap_uim_socket2", UimFuncs);
4621#endif
4622
4623#if (SIM_COUNT >= 3)
4624 RilSapSocket::initSapSocket("sap_uim_socket3", UimFuncs);
4625#endif
4626
4627#if (SIM_COUNT >= 4)
4628 RilSapSocket::initSapSocket("sap_uim_socket4", UimFuncs);
4629#endif
4630 }
4631 }
4632}
4633
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004634static int
4635checkAndDequeueRequestInfo(struct RequestInfo *pRI) {
4636 int ret = 0;
Howard Sue32dbfd2015-01-07 15:55:57 +08004637 /* Hook for current context
4638 pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
4639 pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
4640 /* pendingRequestsHook refer to &s_pendingRequests */
4641 RequestInfo ** pendingRequestsHook = &s_pendingRequests;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004642
4643 if (pRI == NULL) {
4644 return 0;
4645 }
4646
Howard Sue32dbfd2015-01-07 15:55:57 +08004647#if (SIM_COUNT >= 2)
4648 if (pRI->socket_id == RIL_SOCKET_2) {
4649 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
4650 pendingRequestsHook = &s_pendingRequests_socket2;
4651 }
4652#if (SIM_COUNT >= 3)
4653 if (pRI->socket_id == RIL_SOCKET_3) {
4654 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
4655 pendingRequestsHook = &s_pendingRequests_socket3;
4656 }
4657#endif
4658#if (SIM_COUNT >= 4)
4659 if (pRI->socket_id == RIL_SOCKET_4) {
4660 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
4661 pendingRequestsHook = &s_pendingRequests_socket4;
4662 }
4663#endif
4664#endif
4665 pthread_mutex_lock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004666
Howard Sue32dbfd2015-01-07 15:55:57 +08004667 for(RequestInfo **ppCur = pendingRequestsHook
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004668 ; *ppCur != NULL
4669 ; ppCur = &((*ppCur)->p_next)
4670 ) {
4671 if (pRI == *ppCur) {
4672 ret = 1;
4673
4674 *ppCur = (*ppCur)->p_next;
4675 break;
4676 }
4677 }
4678
Howard Sue32dbfd2015-01-07 15:55:57 +08004679 pthread_mutex_unlock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004680
4681 return ret;
4682}
4683
4684
4685extern "C" void
4686RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
4687 RequestInfo *pRI;
4688 int ret;
Howard Sue32dbfd2015-01-07 15:55:57 +08004689 int fd = s_ril_param_socket.fdCommand;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004690 size_t errorOffset;
Howard Sue32dbfd2015-01-07 15:55:57 +08004691 RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004692
4693 pRI = (RequestInfo *)t;
4694
4695 if (!checkAndDequeueRequestInfo(pRI)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004696 RLOGE ("RIL_onRequestComplete: invalid RIL_Token");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004697 return;
4698 }
4699
Howard Sue32dbfd2015-01-07 15:55:57 +08004700 socket_id = pRI->socket_id;
4701#if (SIM_COUNT >= 2)
4702 if (socket_id == RIL_SOCKET_2) {
4703 fd = s_ril_param_socket2.fdCommand;
4704 }
4705#if (SIM_COUNT >= 3)
4706 if (socket_id == RIL_SOCKET_3) {
4707 fd = s_ril_param_socket3.fdCommand;
4708 }
4709#endif
4710#if (SIM_COUNT >= 4)
4711 if (socket_id == RIL_SOCKET_4) {
4712 fd = s_ril_param_socket4.fdCommand;
4713 }
4714#endif
4715#endif
Robert Greenwaltbc29c432015-04-29 16:57:39 -07004716#if VDBG
Howard Sue32dbfd2015-01-07 15:55:57 +08004717 RLOGD("RequestComplete, %s", rilSocketIdToString(socket_id));
Robert Greenwaltbc29c432015-04-29 16:57:39 -07004718#endif
Howard Sue32dbfd2015-01-07 15:55:57 +08004719
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004720 if (pRI->local > 0) {
4721 // Locally issued command...void only!
4722 // response does not go back up the command socket
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004723 RLOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004724
4725 goto done;
4726 }
4727
4728 appendPrintBuf("[%04d]< %s",
4729 pRI->token, requestToString(pRI->pCI->requestNumber));
4730
4731 if (pRI->cancelled == 0) {
4732 Parcel p;
4733
4734 p.writeInt32 (RESPONSE_SOLICITED);
4735 p.writeInt32 (pRI->token);
4736 errorOffset = p.dataPosition();
4737
4738 p.writeInt32 (e);
4739
4740 if (response != NULL) {
4741 // there is a response payload, no matter success or not.
4742 ret = pRI->pCI->responseFunction(p, response, responselen);
4743
4744 /* if an error occurred, rewind and mark it */
4745 if (ret != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004746 RLOGE ("responseFunction error, ret %d", ret);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004747 p.setDataPosition(errorOffset);
4748 p.writeInt32 (ret);
4749 }
4750 }
4751
4752 if (e != RIL_E_SUCCESS) {
4753 appendPrintBuf("%s fails by %s", printBuf, failCauseToString(e));
4754 }
4755
Howard Sue32dbfd2015-01-07 15:55:57 +08004756 if (fd < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004757 RLOGD ("RIL onRequestComplete: Command channel closed");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004758 }
Howard Sue32dbfd2015-01-07 15:55:57 +08004759 sendResponse(p, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004760 }
4761
4762done:
4763 free(pRI);
4764}
4765
Howard Subd82ef12015-04-12 10:25:05 +02004766
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004767static void
4768grabPartialWakeLock() {
4769 acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
4770}
4771
4772static void
4773releaseWakeLock() {
4774 release_wake_lock(ANDROID_WAKE_LOCK_NAME);
4775}
4776
4777/**
4778 * Timer callback to put us back to sleep before the default timeout
4779 */
4780static void
4781wakeTimeoutCallback (void *param) {
4782 // We're using "param != NULL" as a cancellation mechanism
4783 if (param == NULL) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004784 releaseWakeLock();
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004785 }
4786}
4787
4788static int
4789decodeVoiceRadioTechnology (RIL_RadioState radioState) {
4790 switch (radioState) {
4791 case RADIO_STATE_SIM_NOT_READY:
4792 case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
4793 case RADIO_STATE_SIM_READY:
4794 return RADIO_TECH_UMTS;
4795
4796 case RADIO_STATE_RUIM_NOT_READY:
4797 case RADIO_STATE_RUIM_READY:
4798 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
4799 case RADIO_STATE_NV_NOT_READY:
4800 case RADIO_STATE_NV_READY:
4801 return RADIO_TECH_1xRTT;
4802
4803 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004804 RLOGD("decodeVoiceRadioTechnology: Invoked with incorrect RadioState");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004805 return -1;
4806 }
4807}
4808
4809static int
4810decodeCdmaSubscriptionSource (RIL_RadioState radioState) {
4811 switch (radioState) {
4812 case RADIO_STATE_SIM_NOT_READY:
4813 case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
4814 case RADIO_STATE_SIM_READY:
4815 case RADIO_STATE_RUIM_NOT_READY:
4816 case RADIO_STATE_RUIM_READY:
4817 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
4818 return CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM;
4819
4820 case RADIO_STATE_NV_NOT_READY:
4821 case RADIO_STATE_NV_READY:
4822 return CDMA_SUBSCRIPTION_SOURCE_NV;
4823
4824 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004825 RLOGD("decodeCdmaSubscriptionSource: Invoked with incorrect RadioState");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004826 return -1;
4827 }
4828}
4829
4830static int
4831decodeSimStatus (RIL_RadioState radioState) {
4832 switch (radioState) {
4833 case RADIO_STATE_SIM_NOT_READY:
4834 case RADIO_STATE_RUIM_NOT_READY:
4835 case RADIO_STATE_NV_NOT_READY:
4836 case RADIO_STATE_NV_READY:
4837 return -1;
4838 case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
4839 case RADIO_STATE_SIM_READY:
4840 case RADIO_STATE_RUIM_READY:
4841 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
4842 return radioState;
4843 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004844 RLOGD("decodeSimStatus: Invoked with incorrect RadioState");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004845 return -1;
4846 }
4847}
4848
4849static bool is3gpp2(int radioTech) {
4850 switch (radioTech) {
4851 case RADIO_TECH_IS95A:
4852 case RADIO_TECH_IS95B:
4853 case RADIO_TECH_1xRTT:
4854 case RADIO_TECH_EVDO_0:
4855 case RADIO_TECH_EVDO_A:
4856 case RADIO_TECH_EVDO_B:
4857 case RADIO_TECH_EHRPD:
4858 return true;
4859 default:
4860 return false;
4861 }
4862}
4863
4864/* If RIL sends SIM states or RUIM states, store the voice radio
4865 * technology and subscription source information so that they can be
4866 * returned when telephony framework requests them
4867 */
4868static RIL_RadioState
Howard Subd82ef12015-04-12 10:25:05 +02004869processRadioState(RIL_RadioState newRadioState, RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004870
4871 if((newRadioState > RADIO_STATE_UNAVAILABLE) && (newRadioState < RADIO_STATE_ON)) {
4872 int newVoiceRadioTech;
4873 int newCdmaSubscriptionSource;
4874 int newSimStatus;
4875
4876 /* This is old RIL. Decode Subscription source and Voice Radio Technology
4877 from Radio State and send change notifications if there has been a change */
4878 newVoiceRadioTech = decodeVoiceRadioTechnology(newRadioState);
4879 if(newVoiceRadioTech != voiceRadioTech) {
4880 voiceRadioTech = newVoiceRadioTech;
Howard Sue32dbfd2015-01-07 15:55:57 +08004881 RIL_UNSOL_RESPONSE(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED,
4882 &voiceRadioTech, sizeof(voiceRadioTech), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004883 }
4884 if(is3gpp2(newVoiceRadioTech)) {
4885 newCdmaSubscriptionSource = decodeCdmaSubscriptionSource(newRadioState);
4886 if(newCdmaSubscriptionSource != cdmaSubscriptionSource) {
4887 cdmaSubscriptionSource = newCdmaSubscriptionSource;
Howard Sue32dbfd2015-01-07 15:55:57 +08004888 RIL_UNSOL_RESPONSE(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED,
4889 &cdmaSubscriptionSource, sizeof(cdmaSubscriptionSource), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004890 }
4891 }
4892 newSimStatus = decodeSimStatus(newRadioState);
4893 if(newSimStatus != simRuimStatus) {
4894 simRuimStatus = newSimStatus;
Howard Sue32dbfd2015-01-07 15:55:57 +08004895 RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004896 }
4897
4898 /* Send RADIO_ON to telephony */
4899 newRadioState = RADIO_STATE_ON;
4900 }
4901
4902 return newRadioState;
4903}
4904
Howard Subd82ef12015-04-12 10:25:05 +02004905
Howard Sue32dbfd2015-01-07 15:55:57 +08004906#if defined(ANDROID_MULTI_SIM)
4907extern "C"
Andreas Schneider47b2d962015-04-13 22:54:49 +02004908void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
Howard Sue32dbfd2015-01-07 15:55:57 +08004909 size_t datalen, RIL_SOCKET_ID socket_id)
4910#else
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004911extern "C"
Andreas Schneider47b2d962015-04-13 22:54:49 +02004912void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004913 size_t datalen)
Howard Sue32dbfd2015-01-07 15:55:57 +08004914#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004915{
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004916 int ret;
4917 int64_t timeReceived = 0;
4918 bool shouldScheduleTimeout = false;
4919 RIL_RadioState newState;
Howard Sue32dbfd2015-01-07 15:55:57 +08004920 RIL_SOCKET_ID soc_id = RIL_SOCKET_1;
Howard Subd82ef12015-04-12 10:25:05 +02004921 UnsolResponseInfo *pRI = NULL;
Howard Sue32dbfd2015-01-07 15:55:57 +08004922
4923#if defined(ANDROID_MULTI_SIM)
4924 soc_id = socket_id;
4925#endif
4926
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004927
4928 if (s_registerCalled == 0) {
4929 // Ignore RIL_onUnsolicitedResponse before RIL_register
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004930 RLOGW("RIL_onUnsolicitedResponse called before RIL_register");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004931 return;
4932 }
Howard Sue32dbfd2015-01-07 15:55:57 +08004933
Howard Subd82ef12015-04-12 10:25:05 +02004934 /* Hack to include Samsung responses */
4935 if (unsolResponse > RIL_VENDOR_COMMANDS_OFFSET + RIL_UNSOL_RESPONSE_BASE) {
4936 int index = unsolResponse - RIL_VENDOR_COMMANDS_OFFSET - RIL_UNSOL_RESPONSE_BASE;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004937
Howard Subd82ef12015-04-12 10:25:05 +02004938 RLOGD("SAMSUNG: unsolResponse=%d, unsolResponseIndex=%d", unsolResponse, index);
4939
4940 if (index < (int32_t)NUM_ELEMS(s_unsolResponses_v))
4941 pRI = &s_unsolResponses_v[index];
4942 } else {
4943 int index = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
4944 if (index < (int32_t)NUM_ELEMS(s_unsolResponses))
4945 pRI = &s_unsolResponses[index];
4946 }
4947
4948 if (pRI == NULL || pRI->responseFunction == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004949 RLOGE("unsupported unsolicited response code %d", unsolResponse);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004950 return;
4951 }
4952
4953 // Grab a wake lock if needed for this reponse,
4954 // as we exit we'll either release it immediately
4955 // or set a timer to release it later.
Howard Subd82ef12015-04-12 10:25:05 +02004956 switch (pRI->wakeType) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004957 case WAKE_PARTIAL:
4958 grabPartialWakeLock();
4959 shouldScheduleTimeout = true;
4960 break;
4961
4962 case DONT_WAKE:
4963 default:
4964 // No wake lock is grabed so don't set timeout
4965 shouldScheduleTimeout = false;
4966 break;
4967 }
4968
4969 // Mark the time this was received, doing this
4970 // after grabing the wakelock incase getting
4971 // the elapsedRealTime might cause us to goto
4972 // sleep.
4973 if (unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
4974 timeReceived = elapsedRealtime();
4975 }
4976
4977 appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
4978
4979 Parcel p;
4980
4981 p.writeInt32 (RESPONSE_UNSOLICITED);
4982 p.writeInt32 (unsolResponse);
4983
Howard Subd82ef12015-04-12 10:25:05 +02004984 ret = pRI->responseFunction(p, const_cast<void*>(data), datalen);
4985
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004986 if (ret != 0) {
4987 // Problem with the response. Don't continue;
4988 goto error_exit;
4989 }
4990
4991 // some things get more payload
4992 switch(unsolResponse) {
4993 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
Howard Sue32dbfd2015-01-07 15:55:57 +08004994 newState = processRadioState(CALL_ONSTATEREQUEST(soc_id), soc_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004995 p.writeInt32(newState);
4996 appendPrintBuf("%s {%s}", printBuf,
Howard Sue32dbfd2015-01-07 15:55:57 +08004997 radioStateToString(CALL_ONSTATEREQUEST(soc_id)));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004998 break;
4999
5000
5001 case RIL_UNSOL_NITZ_TIME_RECEIVED:
5002 // Store the time that this was received so the
5003 // handler of this message can account for
5004 // the time it takes to arrive and process. In
5005 // particular the system has been known to sleep
5006 // before this message can be processed.
5007 p.writeInt64(timeReceived);
5008 break;
5009 }
5010
Robert Greenwaltbc29c432015-04-29 16:57:39 -07005011#if VDBG
Howard Sue32dbfd2015-01-07 15:55:57 +08005012 RLOGI("%s UNSOLICITED: %s length:%d", rilSocketIdToString(soc_id), requestToString(unsolResponse), p.dataSize());
Robert Greenwaltbc29c432015-04-29 16:57:39 -07005013#endif
Howard Sue32dbfd2015-01-07 15:55:57 +08005014 ret = sendResponse(p, soc_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005015 if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
5016
5017 // Unfortunately, NITZ time is not poll/update like everything
5018 // else in the system. So, if the upstream client isn't connected,
5019 // keep a copy of the last NITZ response (with receive time noted
5020 // above) around so we can deliver it when it is connected
5021
5022 if (s_lastNITZTimeData != NULL) {
5023 free (s_lastNITZTimeData);
5024 s_lastNITZTimeData = NULL;
5025 }
5026
5027 s_lastNITZTimeData = malloc(p.dataSize());
5028 s_lastNITZTimeDataSize = p.dataSize();
5029 memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
5030 }
5031
5032 // For now, we automatically go back to sleep after TIMEVAL_WAKE_TIMEOUT
5033 // FIXME The java code should handshake here to release wake lock
5034
5035 if (shouldScheduleTimeout) {
5036 // Cancel the previous request
5037 if (s_last_wake_timeout_info != NULL) {
5038 s_last_wake_timeout_info->userParam = (void *)1;
5039 }
5040
5041 s_last_wake_timeout_info
5042 = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
5043 &TIMEVAL_WAKE_TIMEOUT);
5044 }
5045
5046 // Normal exit
5047 return;
5048
5049error_exit:
5050 if (shouldScheduleTimeout) {
5051 releaseWakeLock();
5052 }
5053}
5054
5055/** FIXME generalize this if you track UserCAllbackInfo, clear it
5056 when the callback occurs
5057*/
5058static UserCallbackInfo *
5059internalRequestTimedCallback (RIL_TimedCallback callback, void *param,
5060 const struct timeval *relativeTime)
5061{
5062 struct timeval myRelativeTime;
5063 UserCallbackInfo *p_info;
5064
5065 p_info = (UserCallbackInfo *) malloc (sizeof(UserCallbackInfo));
5066
5067 p_info->p_callback = callback;
5068 p_info->userParam = param;
5069
5070 if (relativeTime == NULL) {
5071 /* treat null parameter as a 0 relative time */
5072 memset (&myRelativeTime, 0, sizeof(myRelativeTime));
5073 } else {
5074 /* FIXME I think event_add's tv param is really const anyway */
5075 memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime));
5076 }
5077
5078 ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info);
5079
5080 ril_timer_add(&(p_info->event), &myRelativeTime);
5081
5082 triggerEvLoop();
5083 return p_info;
5084}
5085
5086
5087extern "C" void
5088RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
5089 const struct timeval *relativeTime) {
5090 internalRequestTimedCallback (callback, param, relativeTime);
5091}
5092
5093const char *
5094failCauseToString(RIL_Errno e) {
5095 switch(e) {
5096 case RIL_E_SUCCESS: return "E_SUCCESS";
XpLoDWilDba5c6a32013-07-27 21:12:19 +02005097 case RIL_E_RADIO_NOT_AVAILABLE: return "E_RADIO_NOT_AVAILABLE";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005098 case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE";
5099 case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT";
5100 case RIL_E_SIM_PIN2: return "E_SIM_PIN2";
5101 case RIL_E_SIM_PUK2: return "E_SIM_PUK2";
5102 case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED";
5103 case RIL_E_CANCELLED: return "E_CANCELLED";
5104 case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL";
5105 case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW";
5106 case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY";
5107 case RIL_E_SIM_ABSENT:return "E_SIM_ABSENT";
5108 case RIL_E_ILLEGAL_SIM_OR_ME:return "E_ILLEGAL_SIM_OR_ME";
5109#ifdef FEATURE_MULTIMODE_ANDROID
5110 case RIL_E_SUBSCRIPTION_NOT_AVAILABLE:return "E_SUBSCRIPTION_NOT_AVAILABLE";
5111 case RIL_E_MODE_NOT_SUPPORTED:return "E_MODE_NOT_SUPPORTED";
5112#endif
5113 default: return "<unknown error>";
5114 }
5115}
5116
5117const char *
5118radioStateToString(RIL_RadioState s) {
5119 switch(s) {
5120 case RADIO_STATE_OFF: return "RADIO_OFF";
5121 case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE";
5122 case RADIO_STATE_SIM_NOT_READY: return "RADIO_SIM_NOT_READY";
5123 case RADIO_STATE_SIM_LOCKED_OR_ABSENT: return "RADIO_SIM_LOCKED_OR_ABSENT";
5124 case RADIO_STATE_SIM_READY: return "RADIO_SIM_READY";
5125 case RADIO_STATE_RUIM_NOT_READY:return"RADIO_RUIM_NOT_READY";
5126 case RADIO_STATE_RUIM_READY:return"RADIO_RUIM_READY";
5127 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:return"RADIO_RUIM_LOCKED_OR_ABSENT";
5128 case RADIO_STATE_NV_NOT_READY:return"RADIO_NV_NOT_READY";
5129 case RADIO_STATE_NV_READY:return"RADIO_NV_READY";
5130 case RADIO_STATE_ON:return"RADIO_ON";
5131 default: return "<unknown state>";
5132 }
5133}
5134
5135const char *
5136callStateToString(RIL_CallState s) {
5137 switch(s) {
5138 case RIL_CALL_ACTIVE : return "ACTIVE";
5139 case RIL_CALL_HOLDING: return "HOLDING";
5140 case RIL_CALL_DIALING: return "DIALING";
5141 case RIL_CALL_ALERTING: return "ALERTING";
5142 case RIL_CALL_INCOMING: return "INCOMING";
5143 case RIL_CALL_WAITING: return "WAITING";
5144 default: return "<unknown state>";
5145 }
5146}
5147
5148const char *
5149requestToString(int request) {
5150/*
5151 cat libs/telephony/ril_commands.h \
5152 | egrep "^ *{RIL_" \
5153 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
5154
5155
5156 cat libs/telephony/ril_unsol_commands.h \
5157 | egrep "^ *{RIL_" \
5158 | sed -re 's/\{RIL_([^,]+),([^}]+).+/case RIL_\1: return "\1";/'
5159
5160*/
5161 switch(request) {
5162 case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
5163 case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
5164 case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
5165 case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
5166 case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
5167 case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
5168 case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
5169 case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
5170 case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
5171 case RIL_REQUEST_DIAL: return "DIAL";
5172 case RIL_REQUEST_DIAL_EMERGENCY: return "DIAL";
5173 case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
5174 case RIL_REQUEST_HANGUP: return "HANGUP";
5175 case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
5176 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
5177 case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
5178 case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
5179 case RIL_REQUEST_UDUB: return "UDUB";
5180 case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
5181 case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
5182 case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
5183 case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
5184 case RIL_REQUEST_OPERATOR: return "OPERATOR";
5185 case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
5186 case RIL_REQUEST_DTMF: return "DTMF";
5187 case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
5188 case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
5189 case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
5190 case RIL_REQUEST_SIM_IO: return "SIM_IO";
5191 case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
5192 case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
5193 case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
5194 case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
5195 case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
5196 case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
5197 case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
5198 case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
5199 case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
5200 case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
5201 case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
5202 case RIL_REQUEST_ANSWER: return "ANSWER";
5203 case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
5204 case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
5205 case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
5206 case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
5207 case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
5208 case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
5209 case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
5210 case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
5211 case RIL_REQUEST_DTMF_START: return "DTMF_START";
5212 case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
5213 case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
5214 case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
5215 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE";
5216 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE";
5217 case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS";
5218 case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
5219 case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
5220 case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
5221 case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
5222 case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
5223 case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
5224 case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
5225 case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
5226 case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
5227 case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
5228 case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE";
5229 case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE";
5230 case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND";
5231 case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE";
5232 case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
5233 case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
5234 case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER";
5235 case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES";
XpLoDWilDba5c6a32013-07-27 21:12:19 +02005236 case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:return"CDMA_SET_SUBSCRIPTION_SOURCE";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005237 case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:return"CDMA_SET_ROAMING_PREFERENCE";
5238 case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:return"CDMA_QUERY_ROAMING_PREFERENCE";
5239 case RIL_REQUEST_SET_TTY_MODE:return"SET_TTY_MODE";
5240 case RIL_REQUEST_QUERY_TTY_MODE:return"QUERY_TTY_MODE";
5241 case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
5242 case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
5243 case RIL_REQUEST_CDMA_FLASH:return"CDMA_FLASH";
5244 case RIL_REQUEST_CDMA_BURST_DTMF:return"CDMA_BURST_DTMF";
5245 case RIL_REQUEST_CDMA_SEND_SMS:return"CDMA_SEND_SMS";
5246 case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:return"CDMA_SMS_ACKNOWLEDGE";
5247 case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG:return"GSM_GET_BROADCAST_SMS_CONFIG";
5248 case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG:return"GSM_SET_BROADCAST_SMS_CONFIG";
5249 case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG:return "CDMA_GET_BROADCAST_SMS_CONFIG";
5250 case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG:return "CDMA_SET_BROADCAST_SMS_CONFIG";
5251 case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION:return "CDMA_SMS_BROADCAST_ACTIVATION";
Ethan Chend6e30652013-08-04 22:49:56 -07005252 case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return"CDMA_VALIDATE_AND_WRITE_AKEY";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005253 case RIL_REQUEST_CDMA_SUBSCRIPTION: return"CDMA_SUBSCRIPTION";
5254 case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "CDMA_WRITE_SMS_TO_RUIM";
5255 case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "CDMA_DELETE_SMS_ON_RUIM";
5256 case RIL_REQUEST_DEVICE_IDENTITY: return "DEVICE_IDENTITY";
5257 case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "EXIT_EMERGENCY_CALLBACK_MODE";
5258 case RIL_REQUEST_GET_SMSC_ADDRESS: return "GET_SMSC_ADDRESS";
5259 case RIL_REQUEST_SET_SMSC_ADDRESS: return "SET_SMSC_ADDRESS";
5260 case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "REPORT_SMS_MEMORY_STATUS";
5261 case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "REPORT_STK_SERVICE_IS_RUNNING";
5262 case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "CDMA_GET_SUBSCRIPTION_SOURCE";
5263 case RIL_REQUEST_ISIM_AUTHENTICATION: return "ISIM_AUTHENTICATION";
5264 case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
5265 case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
5266 case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH";
XpLoDWilDba5c6a32013-07-27 21:12:19 +02005267 case RIL_REQUEST_GET_CELL_INFO_LIST: return"GET_CELL_INFO_LIST";
5268 case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return"SET_UNSOL_CELL_INFO_LIST_RATE";
Andrew Jiangca4a9a02014-01-18 18:04:08 -05005269 case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "RIL_REQUEST_SET_INITIAL_ATTACH_APN";
5270 case RIL_REQUEST_IMS_REGISTRATION_STATE: return "IMS_REGISTRATION_STATE";
5271 case RIL_REQUEST_IMS_SEND_SMS: return "IMS_SEND_SMS";
Howard Sue32dbfd2015-01-07 15:55:57 +08005272 case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC: return "SIM_TRANSMIT_APDU_BASIC";
5273 case RIL_REQUEST_SIM_OPEN_CHANNEL: return "SIM_OPEN_CHANNEL";
5274 case RIL_REQUEST_SIM_CLOSE_CHANNEL: return "SIM_CLOSE_CHANNEL";
5275 case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL: return "SIM_TRANSMIT_APDU_CHANNEL";
Howard Subd82ef12015-04-12 10:25:05 +02005276 case RIL_REQUEST_GET_RADIO_CAPABILITY: return "RIL_REQUEST_GET_RADIO_CAPABILITY";
5277 case RIL_REQUEST_SET_RADIO_CAPABILITY: return "RIL_REQUEST_SET_RADIO_CAPABILITY";
Howard Sue32dbfd2015-01-07 15:55:57 +08005278 case RIL_REQUEST_SET_UICC_SUBSCRIPTION: return "SET_UICC_SUBSCRIPTION";
5279 case RIL_REQUEST_ALLOW_DATA: return "ALLOW_DATA";
5280 case RIL_REQUEST_GET_HARDWARE_CONFIG: return "GET_HARDWARE_CONFIG";
5281 case RIL_REQUEST_SIM_AUTHENTICATION: return "SIM_AUTHENTICATION";
5282 case RIL_REQUEST_GET_DC_RT_INFO: return "GET_DC_RT_INFO";
5283 case RIL_REQUEST_SET_DC_RT_INFO_RATE: return "SET_DC_RT_INFO_RATE";
5284 case RIL_REQUEST_SET_DATA_PROFILE: return "SET_DATA_PROFILE";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005285 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
5286 case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
5287 case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
5288 case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
5289 case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
5290 case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
5291 case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
5292 case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
5293 case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
5294 case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
Howard Subd82ef12015-04-12 10:25:05 +02005295 case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
5296 case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005297 case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
5298 case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
5299 case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
5300 case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
5301 case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FUL";
5302 case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005303 case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
5304 case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
5305 case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_NEW_CDMA_SMS";
5306 case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_NEW_BROADCAST_SMS";
5307 case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
5308 case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
5309 case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
5310 case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
5311 case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
5312 case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
5313 case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
5314 case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONE";
5315 case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
5316 case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED";
5317 case RIL_UNSOL_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
5318 case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
5319 case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
5320 case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED";
Ethan Chend6e30652013-08-04 22:49:56 -07005321 case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST";
Andrew Jiangca4a9a02014-01-18 18:04:08 -05005322 case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return "RESPONSE_IMS_NETWORK_STATE_CHANGED";
Howard Sue32dbfd2015-01-07 15:55:57 +08005323 case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED: return "UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED";
5324 case RIL_UNSOL_SRVCC_STATE_NOTIFY: return "UNSOL_SRVCC_STATE_NOTIFY";
5325 case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: return "HARDWARE_CONFIG_CHANGED";
5326 case RIL_UNSOL_DC_RT_INFO_CHANGED: return "UNSOL_DC_RT_INFO_CHANGED";
Howard Subd82ef12015-04-12 10:25:05 +02005327 case RIL_UNSOL_RADIO_CAPABILITY: return "UNSOL_RADIO_CAPABILITY";
5328 case RIL_UNSOL_ON_SS: return "UNSOL_ON_SS";
5329 case RIL_UNSOL_STK_CC_ALPHA_NOTIFY: return "UNSOL_STK_CC_ALPHA_NOTIFY";
Howard Sue32dbfd2015-01-07 15:55:57 +08005330 case RIL_REQUEST_SHUTDOWN: return "SHUTDOWN";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005331 default: return "<unknown request>";
5332 }
5333}
5334
Howard Sue32dbfd2015-01-07 15:55:57 +08005335const char *
5336rilSocketIdToString(RIL_SOCKET_ID socket_id)
5337{
5338 switch(socket_id) {
5339 case RIL_SOCKET_1:
5340 return "RIL_SOCKET_1";
5341#if (SIM_COUNT >= 2)
5342 case RIL_SOCKET_2:
5343 return "RIL_SOCKET_2";
5344#endif
5345#if (SIM_COUNT >= 3)
5346 case RIL_SOCKET_3:
5347 return "RIL_SOCKET_3";
5348#endif
5349#if (SIM_COUNT >= 4)
5350 case RIL_SOCKET_4:
5351 return "RIL_SOCKET_4";
5352#endif
5353 default:
5354 return "not a valid RIL";
5355 }
5356}
5357
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005358} /* namespace android */
Dheeraj Shettycc231012014-07-02 21:27:57 +02005359
5360void rilEventAddWakeup_helper(struct ril_event *ev) {
5361 android::rilEventAddWakeup(ev);
5362}
5363
5364void listenCallback_helper(int fd, short flags, void *param) {
5365 android::listenCallback(fd, flags, param);
5366}
5367
5368int blockingWrite_helper(int fd, void *buffer, size_t len) {
5369 return android::blockingWrite(fd, buffer, len);
5370}