blob: 9f3099958e96745cee328ff51833289f8ccd30f1 [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
67
68#define PROPERTY_RIL_IMPL "gsm.version.ril-impl"
69
70// match with constant in RIL.java
71#define MAX_COMMAND_BYTES (8 * 1024)
72
73// Basically: memset buffers that the client library
74// shouldn't be using anymore in an attempt to find
75// memory usage issues sooner.
76#define MEMSET_FREED 1
77
78#define NUM_ELEMS(a) (sizeof (a) / sizeof (a)[0])
79
80#define MIN(a,b) ((a)<(b) ? (a) : (b))
81
82/* Constants for response types */
83#define RESPONSE_SOLICITED 0
84#define RESPONSE_UNSOLICITED 1
85
86/* Negative values for private RIL errno's */
87#define RIL_ERRNO_INVALID_RESPONSE -1
88
89// request, response, and unsolicited msg print macro
90#define PRINTBUF_SIZE 8096
91
92// Enable RILC log
93#define RILC_LOG 0
94
95#if RILC_LOG
96 #define startRequest sprintf(printBuf, "(")
97 #define closeRequest sprintf(printBuf, "%s)", printBuf)
98 #define printRequest(token, req) \
XpLoDWilDba5c6a32013-07-27 21:12:19 +020099 RLOGD("[%04d]> %s %s", token, requestToString(req), printBuf)
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200100
101 #define startResponse sprintf(printBuf, "%s {", printBuf)
102 #define closeResponse sprintf(printBuf, "%s}", printBuf)
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200103 #define printResponse RLOGD("%s", printBuf)
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200104
105 #define clearPrintBuf printBuf[0] = 0
106 #define removeLastChar printBuf[strlen(printBuf)-1] = 0
107 #define appendPrintBuf(x...) sprintf(printBuf, x)
108#else
109 #define startRequest
110 #define closeRequest
111 #define printRequest(token, req)
112 #define startResponse
113 #define closeResponse
114 #define printResponse
115 #define clearPrintBuf
116 #define removeLastChar
117 #define appendPrintBuf(x...)
118#endif
119
120enum WakeType {DONT_WAKE, WAKE_PARTIAL};
121
122typedef struct {
123 int requestNumber;
124 void (*dispatchFunction) (Parcel &p, struct RequestInfo *pRI);
125 int(*responseFunction) (Parcel &p, void *response, size_t responselen);
126} CommandInfo;
127
128typedef struct {
129 int requestNumber;
130 int (*responseFunction) (Parcel &p, void *response, size_t responselen);
131 WakeType wakeType;
132} UnsolResponseInfo;
133
134typedef struct RequestInfo {
135 int32_t token; //this is not RIL_Token
136 CommandInfo *pCI;
137 struct RequestInfo *p_next;
138 char cancelled;
139 char local; // responses to local commands do not go back to command process
Howard Sue32dbfd2015-01-07 15:55:57 +0800140 RIL_SOCKET_ID socket_id;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200141} RequestInfo;
142
143typedef struct UserCallbackInfo {
144 RIL_TimedCallback p_callback;
145 void *userParam;
146 struct ril_event event;
147 struct UserCallbackInfo *p_next;
148} UserCallbackInfo;
149
Howard Sue32dbfd2015-01-07 15:55:57 +0800150extern "C" const char * requestToString(int request);
151extern "C" const char * failCauseToString(RIL_Errno);
152extern "C" const char * callStateToString(RIL_CallState);
153extern "C" const char * radioStateToString(RIL_RadioState);
154extern "C" const char * rilSocketIdToString(RIL_SOCKET_ID socket_id);
155
156extern "C"
157char rild[MAX_SOCKET_NAME_LENGTH] = SOCKET_NAME_RIL;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200158
Howard Subd82ef12015-04-12 10:25:05 +0200159#define RIL_VENDOR_COMMANDS_OFFSET 10000
160
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200161/*******************************************************************/
162
163RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL};
164static int s_registerCalled = 0;
165
166static pthread_t s_tid_dispatch;
167static pthread_t s_tid_reader;
168static int s_started = 0;
169
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200170static int s_fdDebug = -1;
Howard Sue32dbfd2015-01-07 15:55:57 +0800171static int s_fdDebug_socket2 = -1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200172
173static int s_fdWakeupRead;
174static int s_fdWakeupWrite;
175
176static struct ril_event s_commands_event;
177static struct ril_event s_wakeupfd_event;
178static struct ril_event s_listen_event;
Howard Sue32dbfd2015-01-07 15:55:57 +0800179static SocketListenParam s_ril_param_socket;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200180
181static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER;
182static pthread_mutex_t s_writeMutex = PTHREAD_MUTEX_INITIALIZER;
Howard Sue32dbfd2015-01-07 15:55:57 +0800183static RequestInfo *s_pendingRequests = NULL;
184
185#if (SIM_COUNT >= 2)
186static struct ril_event s_commands_event_socket2;
187static struct ril_event s_listen_event_socket2;
188static SocketListenParam s_ril_param_socket2;
189
190static pthread_mutex_t s_pendingRequestsMutex_socket2 = PTHREAD_MUTEX_INITIALIZER;
191static pthread_mutex_t s_writeMutex_socket2 = PTHREAD_MUTEX_INITIALIZER;
192static RequestInfo *s_pendingRequests_socket2 = NULL;
193#endif
194
195#if (SIM_COUNT >= 3)
196static struct ril_event s_commands_event_socket3;
197static struct ril_event s_listen_event_socket3;
198static SocketListenParam s_ril_param_socket3;
199
200static pthread_mutex_t s_pendingRequestsMutex_socket3 = PTHREAD_MUTEX_INITIALIZER;
201static pthread_mutex_t s_writeMutex_socket3 = PTHREAD_MUTEX_INITIALIZER;
202static RequestInfo *s_pendingRequests_socket3 = NULL;
203#endif
204
205#if (SIM_COUNT >= 4)
206static struct ril_event s_commands_event_socket4;
207static struct ril_event s_listen_event_socket4;
208static SocketListenParam s_ril_param_socket4;
209
210static pthread_mutex_t s_pendingRequestsMutex_socket4 = PTHREAD_MUTEX_INITIALIZER;
211static pthread_mutex_t s_writeMutex_socket4 = PTHREAD_MUTEX_INITIALIZER;
212static RequestInfo *s_pendingRequests_socket4 = NULL;
213#endif
214
215static struct ril_event s_wake_timeout_event;
216static struct ril_event s_debug_event;
217
Howard Subd82ef12015-04-12 10:25:05 +0200218
Howard Sue32dbfd2015-01-07 15:55:57 +0800219static const struct timeval TIMEVAL_WAKE_TIMEOUT = {1,0};
220
Howard Subd82ef12015-04-12 10:25:05 +0200221
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200222static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
223static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER;
224
225static pthread_mutex_t s_dispatchMutex = PTHREAD_MUTEX_INITIALIZER;
226static pthread_cond_t s_dispatchCond = PTHREAD_COND_INITIALIZER;
227
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200228static RequestInfo *s_toDispatchHead = NULL;
229static RequestInfo *s_toDispatchTail = NULL;
230
231static UserCallbackInfo *s_last_wake_timeout_info = NULL;
232
233static void *s_lastNITZTimeData = NULL;
234static size_t s_lastNITZTimeDataSize;
235
236#if RILC_LOG
237 static char printBuf[PRINTBUF_SIZE];
238#endif
239
240/*******************************************************************/
Howard Sue32dbfd2015-01-07 15:55:57 +0800241static int sendResponse (Parcel &p, RIL_SOCKET_ID socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200242
243static void dispatchVoid (Parcel& p, RequestInfo *pRI);
244static void dispatchString (Parcel& p, RequestInfo *pRI);
245static void dispatchStrings (Parcel& p, RequestInfo *pRI);
246static void dispatchInts (Parcel& p, RequestInfo *pRI);
247static void dispatchDial (Parcel& p, RequestInfo *pRI);
248static void dispatchSIM_IO (Parcel& p, RequestInfo *pRI);
Howard Sue32dbfd2015-01-07 15:55:57 +0800249static void dispatchSIM_APDU (Parcel& p, RequestInfo *pRI);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200250static void dispatchCallForward(Parcel& p, RequestInfo *pRI);
251static void dispatchRaw(Parcel& p, RequestInfo *pRI);
252static void dispatchSmsWrite (Parcel &p, RequestInfo *pRI);
253static void dispatchDataCall (Parcel& p, RequestInfo *pRI);
254static void dispatchVoiceRadioTech (Parcel& p, RequestInfo *pRI);
Andrew Jiangca4a9a02014-01-18 18:04:08 -0500255static void dispatchSetInitialAttachApn (Parcel& p, RequestInfo *pRI);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200256static void dispatchCdmaSubscriptionSource (Parcel& p, RequestInfo *pRI);
257
258static void dispatchCdmaSms(Parcel &p, RequestInfo *pRI);
Andrew Jiangca4a9a02014-01-18 18:04:08 -0500259static void dispatchImsSms(Parcel &p, RequestInfo *pRI);
260static void dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef);
261static void dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200262static void dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI);
263static void dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI);
264static void dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI);
265static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI);
Howard Sue32dbfd2015-01-07 15:55:57 +0800266static void dispatchNVReadItem(Parcel &p, RequestInfo *pRI);
267static void dispatchNVWriteItem(Parcel &p, RequestInfo *pRI);
268static void dispatchUiccSubscripton(Parcel &p, RequestInfo *pRI);
269static void dispatchSimAuthentication(Parcel &p, RequestInfo *pRI);
270static void dispatchDataProfile(Parcel &p, RequestInfo *pRI);
Howard Subd82ef12015-04-12 10:25:05 +0200271static void dispatchRadioCapability(Parcel &p, RequestInfo *pRI);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200272static int responseInts(Parcel &p, void *response, size_t responselen);
Daniel Hillenbrandd0b84162015-04-12 11:53:23 +0200273static int responseIntsGetPreferredNetworkType(Parcel &p, void *response, size_t responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200274static int responseStrings(Parcel &p, void *response, size_t responselen);
Utkarsh Guptaf7a63e52015-05-10 16:53:37 +0530275static int responseStringsNetworks(Parcel &p, void *response, size_t responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200276static int responseStrings(Parcel &p, void *response, size_t responselen, bool network_search);
277static int responseString(Parcel &p, void *response, size_t responselen);
278static int responseVoid(Parcel &p, void *response, size_t responselen);
279static int responseCallList(Parcel &p, void *response, size_t responselen);
280static int responseSMS(Parcel &p, void *response, size_t responselen);
281static int responseSIM_IO(Parcel &p, void *response, size_t responselen);
282static int responseCallForwards(Parcel &p, void *response, size_t responselen);
283static int responseDataCallList(Parcel &p, void *response, size_t responselen);
284static int responseSetupDataCall(Parcel &p, void *response, size_t responselen);
285static int responseRaw(Parcel &p, void *response, size_t responselen);
286static int responseSsn(Parcel &p, void *response, size_t responselen);
287static int responseSimStatus(Parcel &p, void *response, size_t responselen);
288static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen);
289static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen);
290static int responseCdmaSms(Parcel &p, void *response, size_t responselen);
291static int responseCellList(Parcel &p, void *response, size_t responselen);
292static int responseCdmaInformationRecords(Parcel &p,void *response, size_t responselen);
293static int responseRilSignalStrength(Parcel &p,void *response, size_t responselen);
294static int responseCallRing(Parcel &p, void *response, size_t responselen);
295static int responseCdmaSignalInfoRecord(Parcel &p,void *response, size_t responselen);
296static int responseCdmaCallWaiting(Parcel &p,void *response, size_t responselen);
297static int responseSimRefresh(Parcel &p, void *response, size_t responselen);
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200298static int responseCellInfoList(Parcel &p, void *response, size_t responselen);
Howard Sue32dbfd2015-01-07 15:55:57 +0800299static int responseHardwareConfig(Parcel &p, void *response, size_t responselen);
300static int responseDcRtInfo(Parcel &p, void *response, size_t responselen);
Howard Subd82ef12015-04-12 10:25:05 +0200301static int responseRadioCapability(Parcel &p, void *response, size_t responselen);
302static int responseSSData(Parcel &p, void *response, size_t responselen);
fenglu9bdede02015-04-14 14:53:55 -0700303static int responseLceStatus(Parcel &p, void *response, size_t responselen);
304static int responseLceData(Parcel &p, void *response, size_t responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200305
306static int decodeVoiceRadioTechnology (RIL_RadioState radioState);
307static int decodeCdmaSubscriptionSource (RIL_RadioState radioState);
Howard Subd82ef12015-04-12 10:25:05 +0200308static RIL_RadioState processRadioState(RIL_RadioState newRadioState);
309
310static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200311
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200312#ifdef RIL_SHLIB
Howard Sue32dbfd2015-01-07 15:55:57 +0800313#if defined(ANDROID_MULTI_SIM)
Andreas Schneider47b2d962015-04-13 22:54:49 +0200314extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
Howard Sue32dbfd2015-01-07 15:55:57 +0800315 size_t datalen, RIL_SOCKET_ID socket_id);
316#else
Andreas Schneider47b2d962015-04-13 22:54:49 +0200317extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200318 size_t datalen);
319#endif
Howard Sue32dbfd2015-01-07 15:55:57 +0800320#endif
321
322#if defined(ANDROID_MULTI_SIM)
323#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c), (d))
324#define CALL_ONREQUEST(a, b, c, d, e) s_callbacks.onRequest((a), (b), (c), (d), (e))
325#define CALL_ONSTATEREQUEST(a) s_callbacks.onStateRequest(a)
326#else
327#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c))
328#define CALL_ONREQUEST(a, b, c, d, e) s_callbacks.onRequest((a), (b), (c), (d))
329#define CALL_ONSTATEREQUEST(a) s_callbacks.onStateRequest()
330#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200331
332static UserCallbackInfo * internalRequestTimedCallback
333 (RIL_TimedCallback callback, void *param,
334 const struct timeval *relativeTime);
335
336/** Index == requestNumber */
337static CommandInfo s_commands[] = {
338#include "ril_commands.h"
339};
340
Howard Subd82ef12015-04-12 10:25:05 +0200341static CommandInfo s_commands_v[] = {
342#include "ril_commands_vendor.h"
343};
344
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200345static UnsolResponseInfo s_unsolResponses[] = {
346#include "ril_unsol_commands.h"
347};
348
Howard Subd82ef12015-04-12 10:25:05 +0200349static UnsolResponseInfo s_unsolResponses_v[] = {
350#include "ril_unsol_commands_vendor.h"
351};
352
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200353/* For older RILs that do not support new commands RIL_REQUEST_VOICE_RADIO_TECH and
354 RIL_UNSOL_VOICE_RADIO_TECH_CHANGED messages, decode the voice radio tech from
355 radio state message and store it. Every time there is a change in Radio State
356 check to see if voice radio tech changes and notify telephony
357 */
358int voiceRadioTech = -1;
359
360/* For older RILs that do not support new commands RIL_REQUEST_GET_CDMA_SUBSCRIPTION_SOURCE
361 and RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED messages, decode the subscription
362 source from radio state and store it. Every time there is a change in Radio State
363 check to see if subscription source changed and notify telephony
364 */
365int cdmaSubscriptionSource = -1;
366
367/* For older RILs that do not send RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, decode the
368 SIM/RUIM state from radio state and store it. Every time there is a change in Radio State,
369 check to see if SIM/RUIM status changed and notify telephony
370 */
371int simRuimStatus = -1;
372
Howard Sue32dbfd2015-01-07 15:55:57 +0800373static char * RIL_getRilSocketName() {
374 return rild;
375}
376
377extern "C"
Dheeraj Shettycc231012014-07-02 21:27:57 +0200378void RIL_setRilSocketName(const char * s) {
Howard Sue32dbfd2015-01-07 15:55:57 +0800379 strncpy(rild, s, MAX_SOCKET_NAME_LENGTH);
380}
381
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200382static char *
383strdupReadString(Parcel &p) {
384 size_t stringlen;
385 const char16_t *s16;
386
387 s16 = p.readString16Inplace(&stringlen);
388
389 return strndup16to8(s16, stringlen);
390}
391
Howard Subd82ef12015-04-12 10:25:05 +0200392static status_t
393readStringFromParcelInplace(Parcel &p, char *str, size_t maxLen) {
394 size_t s16Len;
395 const char16_t *s16;
396
397 s16 = p.readString16Inplace(&s16Len);
398 if (s16 == NULL) {
399 return NO_MEMORY;
400 }
401 size_t strLen = strnlen16to8(s16, s16Len);
402 if ((strLen + 1) > maxLen) {
403 return NO_MEMORY;
404 }
405 if (strncpy16to8(str, s16, strLen) == NULL) {
406 return NO_MEMORY;
407 } else {
408 return NO_ERROR;
409 }
410}
411
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200412static void writeStringToParcel(Parcel &p, const char *s) {
413 char16_t *s16;
414 size_t s16_len;
415 s16 = strdup8to16(s, &s16_len);
416 p.writeString16(s16, s16_len);
417 free(s16);
418}
419
420
421static void
422memsetString (char *s) {
423 if (s != NULL) {
424 memset (s, 0, strlen(s));
425 }
426}
427
428void nullParcelReleaseFunction (const uint8_t* data, size_t dataSize,
429 const size_t* objects, size_t objectsSize,
430 void* cookie) {
431 // do nothing -- the data reference lives longer than the Parcel object
432}
433
434/**
435 * To be called from dispatch thread
436 * Issue a single local request, ensuring that the response
437 * is not sent back up to the command process
438 */
439static void
Howard Sue32dbfd2015-01-07 15:55:57 +0800440issueLocalRequest(int request, void *data, int len, RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200441 RequestInfo *pRI;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200442 int ret;
Howard Sue32dbfd2015-01-07 15:55:57 +0800443 /* Hook for current context */
444 /* pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
445 pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
446 /* pendingRequestsHook refer to &s_pendingRequests */
447 RequestInfo** pendingRequestsHook = &s_pendingRequests;
448
449#if (SIM_COUNT == 2)
450 if (socket_id == RIL_SOCKET_2) {
451 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
452 pendingRequestsHook = &s_pendingRequests_socket2;
453 }
454#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200455
456 pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
457
458 pRI->local = 1;
459 pRI->token = 0xffffffff; // token is not used in this context
460
Howard Subd82ef12015-04-12 10:25:05 +0200461 /* Check vendor commands */
462 if (request > RIL_VENDOR_COMMANDS_OFFSET) {
463 pRI->pCI = &(s_commands_v[request - RIL_VENDOR_COMMANDS_OFFSET]);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200464 } else {
465 pRI->pCI = &(s_commands[request]);
466 }
Howard Sue32dbfd2015-01-07 15:55:57 +0800467 pRI->socket_id = socket_id;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200468
Howard Sue32dbfd2015-01-07 15:55:57 +0800469 ret = pthread_mutex_lock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200470 assert (ret == 0);
471
Howard Sue32dbfd2015-01-07 15:55:57 +0800472 pRI->p_next = *pendingRequestsHook;
473 *pendingRequestsHook = pRI;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200474
Howard Sue32dbfd2015-01-07 15:55:57 +0800475 ret = pthread_mutex_unlock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200476 assert (ret == 0);
477
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200478 RLOGD("C[locl]> %s", requestToString(request));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200479
Howard Sue32dbfd2015-01-07 15:55:57 +0800480 CALL_ONREQUEST(request, data, len, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200481}
482
Howard Subd82ef12015-04-12 10:25:05 +0200483
484
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200485static int
Howard Sue32dbfd2015-01-07 15:55:57 +0800486processCommandBuffer(void *buffer, size_t buflen, RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200487 Parcel p;
488 status_t status;
489 int32_t request;
490 int32_t token;
491 RequestInfo *pRI;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200492 int ret;
Howard Sue32dbfd2015-01-07 15:55:57 +0800493 /* Hook for current context */
494 /* pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
495 pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
496 /* pendingRequestsHook refer to &s_pendingRequests */
497 RequestInfo** pendingRequestsHook = &s_pendingRequests;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200498
499 p.setData((uint8_t *) buffer, buflen);
500
501 // status checked at end
502 status = p.readInt32(&request);
503 status = p.readInt32 (&token);
504
Howard Sue32dbfd2015-01-07 15:55:57 +0800505#if (SIM_COUNT >= 2)
506 if (socket_id == RIL_SOCKET_2) {
507 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
508 pendingRequestsHook = &s_pendingRequests_socket2;
509 }
510#if (SIM_COUNT >= 3)
511 else if (socket_id == RIL_SOCKET_3) {
512 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
513 pendingRequestsHook = &s_pendingRequests_socket3;
514 }
515#endif
516#if (SIM_COUNT >= 4)
517 else if (socket_id == RIL_SOCKET_4) {
518 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
519 pendingRequestsHook = &s_pendingRequests_socket4;
520 }
521#endif
522#endif
523
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200524 if (status != NO_ERROR) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200525 RLOGE("invalid request block");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200526 return 0;
527 }
528
Howard Subd82ef12015-04-12 10:25:05 +0200529 CommandInfo *pCI = NULL;
530 if (request > RIL_VENDOR_COMMANDS_OFFSET) {
531 int index = request - RIL_VENDOR_COMMANDS_OFFSET;
532 RLOGD("processCommandBuffer: samsung request=%d, index=%d",
533 request, index);
534 if (index < (int32_t)NUM_ELEMS(s_commands_v))
535 pCI = &(s_commands_v[index]);
536 } else {
537 if (request < (int32_t)NUM_ELEMS(s_commands))
538 pCI = &(s_commands[request]);
539 }
Howard Sue32dbfd2015-01-07 15:55:57 +0800540
Howard Subd82ef12015-04-12 10:25:05 +0200541 if (pCI == NULL) {
542 Parcel pErr;
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200543 RLOGE("unsupported request code %d token %d", request, token);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200544 // FIXME this should perhaps return a response
Howard Sue32dbfd2015-01-07 15:55:57 +0800545 pErr.writeInt32 (RESPONSE_SOLICITED);
546 pErr.writeInt32 (token);
547 pErr.writeInt32 (RIL_E_GENERIC_FAILURE);
548
549 sendResponse(pErr, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200550 return 0;
551 }
552
553 pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
554
555 pRI->token = token;
Howard Subd82ef12015-04-12 10:25:05 +0200556 pRI->pCI = pCI;
Howard Sue32dbfd2015-01-07 15:55:57 +0800557 pRI->socket_id = socket_id;
558
559 ret = pthread_mutex_lock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200560 assert (ret == 0);
561
Howard Sue32dbfd2015-01-07 15:55:57 +0800562 pRI->p_next = *pendingRequestsHook;
563 *pendingRequestsHook = pRI;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200564
Howard Sue32dbfd2015-01-07 15:55:57 +0800565 ret = pthread_mutex_unlock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200566 assert (ret == 0);
567
568/* sLastDispatchedToken = token; */
569
570 pRI->pCI->dispatchFunction(p, pRI);
571
572 return 0;
573}
574
575static void
576invalidCommandBlock (RequestInfo *pRI) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +0200577 RLOGE("invalid command block for token %d request %s",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200578 pRI->token, requestToString(pRI->pCI->requestNumber));
579}
580
581/** Callee expects NULL */
582static void
583dispatchVoid (Parcel& p, RequestInfo *pRI) {
584 clearPrintBuf;
585 printRequest(pRI->token, pRI->pCI->requestNumber);
Howard Sue32dbfd2015-01-07 15:55:57 +0800586 CALL_ONREQUEST(pRI->pCI->requestNumber, NULL, 0, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200587}
588
589/** Callee expects const char * */
590static void
591dispatchString (Parcel& p, RequestInfo *pRI) {
592 status_t status;
593 size_t datalen;
594 size_t stringlen;
595 char *string8 = NULL;
596
597 string8 = strdupReadString(p);
598
599 startRequest;
600 appendPrintBuf("%s%s", printBuf, string8);
601 closeRequest;
602 printRequest(pRI->token, pRI->pCI->requestNumber);
603
Howard Sue32dbfd2015-01-07 15:55:57 +0800604 CALL_ONREQUEST(pRI->pCI->requestNumber, string8,
605 sizeof(char *), pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200606
607#ifdef MEMSET_FREED
608 memsetString(string8);
609#endif
610
611 free(string8);
612 return;
613invalid:
614 invalidCommandBlock(pRI);
615 return;
616}
617
618/** Callee expects const char ** */
619static void
620dispatchStrings (Parcel &p, RequestInfo *pRI) {
621 int32_t countStrings;
622 status_t status;
623 size_t datalen;
624 char **pStrings;
625
626 status = p.readInt32 (&countStrings);
627
628 if (status != NO_ERROR) {
629 goto invalid;
630 }
631
632 startRequest;
633 if (countStrings == 0) {
634 // just some non-null pointer
635 pStrings = (char **)alloca(sizeof(char *));
636 datalen = 0;
637 } else if (((int)countStrings) == -1) {
638 pStrings = NULL;
639 datalen = 0;
640 } else {
641 datalen = sizeof(char *) * countStrings;
642
643 pStrings = (char **)alloca(datalen);
644
645 for (int i = 0 ; i < countStrings ; i++) {
646 pStrings[i] = strdupReadString(p);
647 appendPrintBuf("%s%s,", printBuf, pStrings[i]);
648 }
649 }
650 removeLastChar;
651 closeRequest;
652 printRequest(pRI->token, pRI->pCI->requestNumber);
653
Howard Sue32dbfd2015-01-07 15:55:57 +0800654 CALL_ONREQUEST(pRI->pCI->requestNumber, pStrings, datalen, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200655
656 if (pStrings != NULL) {
657 for (int i = 0 ; i < countStrings ; i++) {
658#ifdef MEMSET_FREED
659 memsetString (pStrings[i]);
660#endif
661 free(pStrings[i]);
662 }
663
664#ifdef MEMSET_FREED
665 memset(pStrings, 0, datalen);
666#endif
667 }
668
669 return;
670invalid:
671 invalidCommandBlock(pRI);
672 return;
673}
674
675/** Callee expects const int * */
676static void
677dispatchInts (Parcel &p, RequestInfo *pRI) {
678 int32_t count;
679 status_t status;
680 size_t datalen;
681 int *pInts;
682
683 status = p.readInt32 (&count);
684
685 if (status != NO_ERROR || count == 0) {
686 goto invalid;
687 }
688
689 datalen = sizeof(int) * count;
690 pInts = (int *)alloca(datalen);
691
692 startRequest;
693 for (int i = 0 ; i < count ; i++) {
694 int32_t t;
695
696 status = p.readInt32(&t);
697 pInts[i] = (int)t;
698 appendPrintBuf("%s%d,", printBuf, t);
699
700 if (status != NO_ERROR) {
701 goto invalid;
702 }
703 }
704 removeLastChar;
705 closeRequest;
706 printRequest(pRI->token, pRI->pCI->requestNumber);
707
Howard Sue32dbfd2015-01-07 15:55:57 +0800708 CALL_ONREQUEST(pRI->pCI->requestNumber, const_cast<int *>(pInts),
709 datalen, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200710
711#ifdef MEMSET_FREED
712 memset(pInts, 0, datalen);
713#endif
714
715 return;
716invalid:
717 invalidCommandBlock(pRI);
718 return;
719}
720
721
722/**
723 * Callee expects const RIL_SMS_WriteArgs *
724 * Payload is:
725 * int32_t status
726 * String pdu
727 */
728static void
729dispatchSmsWrite (Parcel &p, RequestInfo *pRI) {
730 RIL_SMS_WriteArgs args;
731 int32_t t;
732 status_t status;
733
Mark Salyzyn961fd022015-04-09 07:18:35 -0700734 RLOGD("dispatchSmsWrite");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200735 memset (&args, 0, sizeof(args));
736
737 status = p.readInt32(&t);
738 args.status = (int)t;
739
740 args.pdu = strdupReadString(p);
741
742 if (status != NO_ERROR || args.pdu == NULL) {
743 goto invalid;
744 }
745
746 args.smsc = strdupReadString(p);
747
748 startRequest;
749 appendPrintBuf("%s%d,%s,smsc=%s", printBuf, args.status,
750 (char*)args.pdu, (char*)args.smsc);
751 closeRequest;
752 printRequest(pRI->token, pRI->pCI->requestNumber);
753
Howard Sue32dbfd2015-01-07 15:55:57 +0800754 CALL_ONREQUEST(pRI->pCI->requestNumber, &args, sizeof(args), pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200755
756#ifdef MEMSET_FREED
757 memsetString (args.pdu);
758#endif
759
760 free (args.pdu);
761
762#ifdef MEMSET_FREED
763 memset(&args, 0, sizeof(args));
764#endif
765
766 return;
767invalid:
768 invalidCommandBlock(pRI);
769 return;
770}
771
772/**
773 * Callee expects const RIL_Dial *
774 * Payload is:
775 * String address
776 * int32_t clir
777 */
778static void
779dispatchDial (Parcel &p, RequestInfo *pRI) {
780 RIL_Dial dial;
781 RIL_UUS_Info uusInfo;
782 int32_t sizeOfDial;
783 int32_t t;
784 int32_t uusPresent;
Christopher N. Hesse7bf409e2015-06-26 14:53:56 +0200785#if defined(MODEM_TYPE_XMM7260) || defined(MODEM_TYPE_M7450)
Andreas Schneider29472682015-01-01 19:00:04 +0100786 char *csv;
787#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200788 status_t status;
789
Mark Salyzyn961fd022015-04-09 07:18:35 -0700790 RLOGD("dispatchDial");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200791 memset (&dial, 0, sizeof(dial));
792
793 dial.address = strdupReadString(p);
794
795 status = p.readInt32(&t);
796 dial.clir = (int)t;
797
798 if (status != NO_ERROR || dial.address == NULL) {
799 goto invalid;
800 }
801
Christopher N. Hesse7bf409e2015-06-26 14:53:56 +0200802#if defined(MODEM_TYPE_XMM7260) || defined(MODEM_TYPE_M7450)
Andreas Schneider29472682015-01-01 19:00:04 +0100803 /* CallDetails.call_type */
804 status = p.readInt32(&t);
805 if (status != NO_ERROR) {
806 goto invalid;
807 }
808 /* CallDetails.call_domain */
809 p.readInt32(&t);
810 if (status != NO_ERROR) {
811 goto invalid;
812 }
813 /* CallDetails.getCsvFromExtra */
814 csv = strdupReadString(p);
815 if (csv == NULL) {
816 goto invalid;
817 }
818 free(csv);
819#endif
820
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200821 if (s_callbacks.version < 3) { // Remove when partners upgrade to version 3
822 uusPresent = 0;
823 sizeOfDial = sizeof(dial) - sizeof(RIL_UUS_Info *);
824 } else {
825 status = p.readInt32(&uusPresent);
826
827 if (status != NO_ERROR) {
828 goto invalid;
829 }
830
831 if (uusPresent == 0) {
Christopher N. Hesse7bf409e2015-06-26 14:53:56 +0200832#if defined(MODEM_TYPE_XMM6262) || defined(MODEM_TYPE_XMM7260) || defined(MODEM_TYPE_M7450)
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200833 dial.uusInfo = NULL;
Andreas Schneiderf68609b2015-04-07 19:01:34 +0200834#elif defined(MODEM_TYPE_XMM6260)
Howard Sue32dbfd2015-01-07 15:55:57 +0800835 /* Samsung hack */
836 memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
837 uusInfo.uusType = (RIL_UUS_Type) 0;
838 uusInfo.uusDcs = (RIL_UUS_DCS) 0;
839 uusInfo.uusData = NULL;
840 uusInfo.uusLength = 0;
841 dial.uusInfo = &uusInfo;
842#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200843 } else {
844 int32_t len;
845
846 memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
847
848 status = p.readInt32(&t);
849 uusInfo.uusType = (RIL_UUS_Type) t;
850
851 status = p.readInt32(&t);
852 uusInfo.uusDcs = (RIL_UUS_DCS) t;
853
854 status = p.readInt32(&len);
855 if (status != NO_ERROR) {
856 goto invalid;
857 }
858
859 // The java code writes -1 for null arrays
860 if (((int) len) == -1) {
861 uusInfo.uusData = NULL;
862 len = 0;
863 } else {
864 uusInfo.uusData = (char*) p.readInplace(len);
865 }
866
867 uusInfo.uusLength = len;
868 dial.uusInfo = &uusInfo;
869 }
870 sizeOfDial = sizeof(dial);
871 }
872
873 startRequest;
874 appendPrintBuf("%snum=%s,clir=%d", printBuf, dial.address, dial.clir);
875 if (uusPresent) {
876 appendPrintBuf("%s,uusType=%d,uusDcs=%d,uusLen=%d", printBuf,
877 dial.uusInfo->uusType, dial.uusInfo->uusDcs,
878 dial.uusInfo->uusLength);
879 }
880 closeRequest;
881 printRequest(pRI->token, pRI->pCI->requestNumber);
882
Howard Sue32dbfd2015-01-07 15:55:57 +0800883 CALL_ONREQUEST(pRI->pCI->requestNumber, &dial, sizeOfDial, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200884
885#ifdef MEMSET_FREED
886 memsetString (dial.address);
887#endif
888
889 free (dial.address);
890
891#ifdef MEMSET_FREED
892 memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
893 memset(&dial, 0, sizeof(dial));
894#endif
895
896 return;
897invalid:
898 invalidCommandBlock(pRI);
899 return;
900}
901
902/**
903 * Callee expects const RIL_SIM_IO *
904 * Payload is:
905 * int32_t command
906 * int32_t fileid
907 * String path
908 * int32_t p1, p2, p3
909 * String data
910 * String pin2
911 * String aidPtr
912 */
913static void
914dispatchSIM_IO (Parcel &p, RequestInfo *pRI) {
915 union RIL_SIM_IO {
916 RIL_SIM_IO_v6 v6;
917 RIL_SIM_IO_v5 v5;
918 } simIO;
919
920 int32_t t;
921 int size;
922 status_t status;
923
Mark Salyzyn961fd022015-04-09 07:18:35 -0700924 RLOGD("dispatchSIM_IO");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200925 memset (&simIO, 0, sizeof(simIO));
926
927 // note we only check status at the end
928
929 status = p.readInt32(&t);
930 simIO.v6.command = (int)t;
931
932 status = p.readInt32(&t);
933 simIO.v6.fileid = (int)t;
934
935 simIO.v6.path = strdupReadString(p);
936
937 status = p.readInt32(&t);
938 simIO.v6.p1 = (int)t;
939
940 status = p.readInt32(&t);
941 simIO.v6.p2 = (int)t;
942
943 status = p.readInt32(&t);
944 simIO.v6.p3 = (int)t;
945
946 simIO.v6.data = strdupReadString(p);
947 simIO.v6.pin2 = strdupReadString(p);
948 simIO.v6.aidPtr = strdupReadString(p);
949
950 startRequest;
951 appendPrintBuf("%scmd=0x%X,efid=0x%X,path=%s,%d,%d,%d,%s,pin2=%s,aid=%s", printBuf,
952 simIO.v6.command, simIO.v6.fileid, (char*)simIO.v6.path,
953 simIO.v6.p1, simIO.v6.p2, simIO.v6.p3,
954 (char*)simIO.v6.data, (char*)simIO.v6.pin2, simIO.v6.aidPtr);
955 closeRequest;
956 printRequest(pRI->token, pRI->pCI->requestNumber);
957
958 if (status != NO_ERROR) {
959 goto invalid;
960 }
961
962 size = (s_callbacks.version < 6) ? sizeof(simIO.v5) : sizeof(simIO.v6);
Howard Sue32dbfd2015-01-07 15:55:57 +0800963 CALL_ONREQUEST(pRI->pCI->requestNumber, &simIO, size, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +0200964
965#ifdef MEMSET_FREED
966 memsetString (simIO.v6.path);
967 memsetString (simIO.v6.data);
968 memsetString (simIO.v6.pin2);
969 memsetString (simIO.v6.aidPtr);
970#endif
971
972 free (simIO.v6.path);
973 free (simIO.v6.data);
974 free (simIO.v6.pin2);
975 free (simIO.v6.aidPtr);
976
977#ifdef MEMSET_FREED
978 memset(&simIO, 0, sizeof(simIO));
979#endif
980
981 return;
982invalid:
983 invalidCommandBlock(pRI);
984 return;
985}
986
987/**
Howard Sue32dbfd2015-01-07 15:55:57 +0800988 * Callee expects const RIL_SIM_APDU *
989 * Payload is:
990 * int32_t sessionid
991 * int32_t cla
992 * int32_t instruction
993 * int32_t p1, p2, p3
994 * String data
995 */
996static void
997dispatchSIM_APDU (Parcel &p, RequestInfo *pRI) {
998 int32_t t;
999 status_t status;
1000 RIL_SIM_APDU apdu;
1001
Mark Salyzyn961fd022015-04-09 07:18:35 -07001002 RLOGD("dispatchSIM_APDU");
Howard Sue32dbfd2015-01-07 15:55:57 +08001003 memset (&apdu, 0, sizeof(RIL_SIM_APDU));
1004
1005 // Note we only check status at the end. Any single failure leads to
1006 // subsequent reads filing.
1007 status = p.readInt32(&t);
1008 apdu.sessionid = (int)t;
1009
1010 status = p.readInt32(&t);
1011 apdu.cla = (int)t;
1012
1013 status = p.readInt32(&t);
1014 apdu.instruction = (int)t;
1015
1016 status = p.readInt32(&t);
1017 apdu.p1 = (int)t;
1018
1019 status = p.readInt32(&t);
1020 apdu.p2 = (int)t;
1021
1022 status = p.readInt32(&t);
1023 apdu.p3 = (int)t;
1024
1025 apdu.data = strdupReadString(p);
1026
1027 startRequest;
1028 appendPrintBuf("%ssessionid=%d,cla=%d,ins=%d,p1=%d,p2=%d,p3=%d,data=%s",
1029 printBuf, apdu.sessionid, apdu.cla, apdu.instruction, apdu.p1, apdu.p2,
1030 apdu.p3, (char*)apdu.data);
1031 closeRequest;
1032 printRequest(pRI->token, pRI->pCI->requestNumber);
1033
1034 if (status != NO_ERROR) {
1035 goto invalid;
1036 }
1037
1038 CALL_ONREQUEST(pRI->pCI->requestNumber, &apdu, sizeof(RIL_SIM_APDU), pRI, pRI->socket_id);
1039
1040#ifdef MEMSET_FREED
1041 memsetString(apdu.data);
1042#endif
1043 free(apdu.data);
1044
1045#ifdef MEMSET_FREED
1046 memset(&apdu, 0, sizeof(RIL_SIM_APDU));
1047#endif
1048
1049 return;
1050invalid:
1051 invalidCommandBlock(pRI);
1052 return;
1053}
1054
Howard Subd82ef12015-04-12 10:25:05 +02001055
Howard Sue32dbfd2015-01-07 15:55:57 +08001056/**
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001057 * Callee expects const RIL_CallForwardInfo *
1058 * Payload is:
1059 * int32_t status/action
1060 * int32_t reason
1061 * int32_t serviceCode
1062 * int32_t toa
1063 * String number (0 length -> null)
1064 * int32_t timeSeconds
1065 */
1066static void
1067dispatchCallForward(Parcel &p, RequestInfo *pRI) {
1068 RIL_CallForwardInfo cff;
1069 int32_t t;
1070 status_t status;
1071
Mark Salyzyn961fd022015-04-09 07:18:35 -07001072 RLOGD("dispatchCallForward");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001073 memset (&cff, 0, sizeof(cff));
1074
1075 // note we only check status at the end
1076
1077 status = p.readInt32(&t);
1078 cff.status = (int)t;
1079
1080 status = p.readInt32(&t);
1081 cff.reason = (int)t;
1082
1083 status = p.readInt32(&t);
1084 cff.serviceClass = (int)t;
1085
1086 status = p.readInt32(&t);
1087 cff.toa = (int)t;
1088
1089 cff.number = strdupReadString(p);
1090
1091 status = p.readInt32(&t);
1092 cff.timeSeconds = (int)t;
1093
1094 if (status != NO_ERROR) {
1095 goto invalid;
1096 }
1097
1098 // special case: number 0-length fields is null
1099
1100 if (cff.number != NULL && strlen (cff.number) == 0) {
1101 cff.number = NULL;
1102 }
1103
1104 startRequest;
1105 appendPrintBuf("%sstat=%d,reason=%d,serv=%d,toa=%d,%s,tout=%d", printBuf,
1106 cff.status, cff.reason, cff.serviceClass, cff.toa,
1107 (char*)cff.number, cff.timeSeconds);
1108 closeRequest;
1109 printRequest(pRI->token, pRI->pCI->requestNumber);
1110
Howard Sue32dbfd2015-01-07 15:55:57 +08001111 CALL_ONREQUEST(pRI->pCI->requestNumber, &cff, sizeof(cff), pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001112
1113#ifdef MEMSET_FREED
1114 memsetString(cff.number);
1115#endif
1116
1117 free (cff.number);
1118
1119#ifdef MEMSET_FREED
1120 memset(&cff, 0, sizeof(cff));
1121#endif
1122
1123 return;
1124invalid:
1125 invalidCommandBlock(pRI);
1126 return;
1127}
1128
1129
1130static void
1131dispatchRaw(Parcel &p, RequestInfo *pRI) {
1132 int32_t len;
1133 status_t status;
1134 const void *data;
1135
1136 status = p.readInt32(&len);
1137
1138 if (status != NO_ERROR) {
1139 goto invalid;
1140 }
1141
1142 // The java code writes -1 for null arrays
1143 if (((int)len) == -1) {
1144 data = NULL;
1145 len = 0;
1146 }
1147
1148 data = p.readInplace(len);
1149
1150 startRequest;
1151 appendPrintBuf("%sraw_size=%d", printBuf, len);
1152 closeRequest;
1153 printRequest(pRI->token, pRI->pCI->requestNumber);
1154
Howard Sue32dbfd2015-01-07 15:55:57 +08001155 CALL_ONREQUEST(pRI->pCI->requestNumber, const_cast<void *>(data), len, pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001156
1157 return;
1158invalid:
1159 invalidCommandBlock(pRI);
1160 return;
1161}
1162
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001163static status_t
1164constructCdmaSms(Parcel &p, RequestInfo *pRI, RIL_CDMA_SMS_Message& rcsm) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001165 int32_t t;
1166 uint8_t ut;
1167 status_t status;
1168 int32_t digitCount;
1169 int digitLimit;
1170
1171 memset(&rcsm, 0, sizeof(rcsm));
1172
1173 status = p.readInt32(&t);
1174 rcsm.uTeleserviceID = (int) t;
1175
1176 status = p.read(&ut,sizeof(ut));
1177 rcsm.bIsServicePresent = (uint8_t) ut;
1178
1179 status = p.readInt32(&t);
1180 rcsm.uServicecategory = (int) t;
1181
1182 status = p.readInt32(&t);
1183 rcsm.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
1184
1185 status = p.readInt32(&t);
1186 rcsm.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
1187
1188 status = p.readInt32(&t);
1189 rcsm.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
1190
1191 status = p.readInt32(&t);
1192 rcsm.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
1193
1194 status = p.read(&ut,sizeof(ut));
1195 rcsm.sAddress.number_of_digits= (uint8_t) ut;
1196
1197 digitLimit= MIN((rcsm.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
1198 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1199 status = p.read(&ut,sizeof(ut));
1200 rcsm.sAddress.digits[digitCount] = (uint8_t) ut;
1201 }
1202
1203 status = p.readInt32(&t);
1204 rcsm.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
1205
1206 status = p.read(&ut,sizeof(ut));
1207 rcsm.sSubAddress.odd = (uint8_t) ut;
1208
1209 status = p.read(&ut,sizeof(ut));
1210 rcsm.sSubAddress.number_of_digits = (uint8_t) ut;
1211
1212 digitLimit= MIN((rcsm.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
1213 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1214 status = p.read(&ut,sizeof(ut));
1215 rcsm.sSubAddress.digits[digitCount] = (uint8_t) ut;
1216 }
1217
1218 status = p.readInt32(&t);
1219 rcsm.uBearerDataLen = (int) t;
1220
1221 digitLimit= MIN((rcsm.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
1222 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
1223 status = p.read(&ut, sizeof(ut));
1224 rcsm.aBearerData[digitCount] = (uint8_t) ut;
1225 }
1226
1227 if (status != NO_ERROR) {
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001228 return status;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001229 }
1230
1231 startRequest;
1232 appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
1233 sAddress.digit_mode=%d, sAddress.Number_mode=%d, sAddress.number_type=%d, ",
1234 printBuf, rcsm.uTeleserviceID,rcsm.bIsServicePresent,rcsm.uServicecategory,
1235 rcsm.sAddress.digit_mode, rcsm.sAddress.number_mode,rcsm.sAddress.number_type);
1236 closeRequest;
1237
1238 printRequest(pRI->token, pRI->pCI->requestNumber);
1239
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001240 return status;
1241}
1242
1243static void
1244dispatchCdmaSms(Parcel &p, RequestInfo *pRI) {
1245 RIL_CDMA_SMS_Message rcsm;
1246
Mark Salyzyn961fd022015-04-09 07:18:35 -07001247 RLOGD("dispatchCdmaSms");
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001248 if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) {
1249 goto invalid;
1250 }
1251
Howard Sue32dbfd2015-01-07 15:55:57 +08001252 CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm),pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001253
1254#ifdef MEMSET_FREED
1255 memset(&rcsm, 0, sizeof(rcsm));
1256#endif
1257
1258 return;
1259
1260invalid:
1261 invalidCommandBlock(pRI);
1262 return;
1263}
1264
1265static void
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001266dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) {
1267 RIL_IMS_SMS_Message rism;
1268 RIL_CDMA_SMS_Message rcsm;
1269
Mark Salyzyn961fd022015-04-09 07:18:35 -07001270 RLOGD("dispatchImsCdmaSms: retry=%d, messageRef=%d", retry, messageRef);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001271
1272 if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) {
1273 goto invalid;
1274 }
1275 memset(&rism, 0, sizeof(rism));
1276 rism.tech = RADIO_TECH_3GPP2;
1277 rism.retry = retry;
1278 rism.messageRef = messageRef;
1279 rism.message.cdmaMessage = &rcsm;
1280
Howard Sue32dbfd2015-01-07 15:55:57 +08001281 CALL_ONREQUEST(pRI->pCI->requestNumber, &rism,
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001282 sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t)
Howard Sue32dbfd2015-01-07 15:55:57 +08001283 +sizeof(rcsm),pRI, pRI->socket_id);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001284
1285#ifdef MEMSET_FREED
1286 memset(&rcsm, 0, sizeof(rcsm));
1287 memset(&rism, 0, sizeof(rism));
1288#endif
1289
1290 return;
1291
1292invalid:
1293 invalidCommandBlock(pRI);
1294 return;
1295}
1296
1297static void
1298dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) {
1299 RIL_IMS_SMS_Message rism;
1300 int32_t countStrings;
1301 status_t status;
1302 size_t datalen;
1303 char **pStrings;
Mark Salyzyn961fd022015-04-09 07:18:35 -07001304 RLOGD("dispatchImsGsmSms: retry=%d, messageRef=%d", retry, messageRef);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001305
1306 status = p.readInt32 (&countStrings);
1307
1308 if (status != NO_ERROR) {
1309 goto invalid;
1310 }
1311
1312 memset(&rism, 0, sizeof(rism));
1313 rism.tech = RADIO_TECH_3GPP;
1314 rism.retry = retry;
1315 rism.messageRef = messageRef;
1316
1317 startRequest;
Howard Sue32dbfd2015-01-07 15:55:57 +08001318 appendPrintBuf("%stech=%d, retry=%d, messageRef=%d, ", printBuf,
1319 (int)rism.tech, (int)rism.retry, rism.messageRef);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001320 if (countStrings == 0) {
1321 // just some non-null pointer
1322 pStrings = (char **)alloca(sizeof(char *));
1323 datalen = 0;
1324 } else if (((int)countStrings) == -1) {
1325 pStrings = NULL;
1326 datalen = 0;
1327 } else {
1328 datalen = sizeof(char *) * countStrings;
1329
1330 pStrings = (char **)alloca(datalen);
1331
1332 for (int i = 0 ; i < countStrings ; i++) {
1333 pStrings[i] = strdupReadString(p);
1334 appendPrintBuf("%s%s,", printBuf, pStrings[i]);
1335 }
1336 }
1337 removeLastChar;
1338 closeRequest;
1339 printRequest(pRI->token, pRI->pCI->requestNumber);
1340
1341 rism.message.gsmMessage = pStrings;
Howard Sue32dbfd2015-01-07 15:55:57 +08001342 CALL_ONREQUEST(pRI->pCI->requestNumber, &rism,
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001343 sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t)
Howard Sue32dbfd2015-01-07 15:55:57 +08001344 +datalen, pRI, pRI->socket_id);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001345
1346 if (pStrings != NULL) {
1347 for (int i = 0 ; i < countStrings ; i++) {
1348#ifdef MEMSET_FREED
1349 memsetString (pStrings[i]);
1350#endif
1351 free(pStrings[i]);
1352 }
1353
1354#ifdef MEMSET_FREED
1355 memset(pStrings, 0, datalen);
1356#endif
1357 }
1358
1359#ifdef MEMSET_FREED
1360 memset(&rism, 0, sizeof(rism));
1361#endif
1362 return;
1363invalid:
1364 ALOGE("dispatchImsGsmSms invalid block");
1365 invalidCommandBlock(pRI);
1366 return;
1367}
1368
1369static void
1370dispatchImsSms(Parcel &p, RequestInfo *pRI) {
1371 int32_t t;
1372 status_t status = p.readInt32(&t);
1373 RIL_RadioTechnologyFamily format;
1374 uint8_t retry;
1375 int32_t messageRef;
1376
Mark Salyzyn961fd022015-04-09 07:18:35 -07001377 RLOGD("dispatchImsSms");
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001378 if (status != NO_ERROR) {
1379 goto invalid;
1380 }
1381 format = (RIL_RadioTechnologyFamily) t;
1382
1383 // read retry field
1384 status = p.read(&retry,sizeof(retry));
1385 if (status != NO_ERROR) {
1386 goto invalid;
1387 }
1388 // read messageRef field
1389 status = p.read(&messageRef,sizeof(messageRef));
1390 if (status != NO_ERROR) {
1391 goto invalid;
1392 }
1393
1394 if (RADIO_TECH_3GPP == format) {
1395 dispatchImsGsmSms(p, pRI, retry, messageRef);
1396 } else if (RADIO_TECH_3GPP2 == format) {
1397 dispatchImsCdmaSms(p, pRI, retry, messageRef);
1398 } else {
1399 ALOGE("requestImsSendSMS invalid format value =%d", format);
1400 }
1401
1402 return;
1403
1404invalid:
1405 invalidCommandBlock(pRI);
1406 return;
1407}
1408
1409static void
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001410dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI) {
1411 RIL_CDMA_SMS_Ack rcsa;
1412 int32_t t;
1413 status_t status;
1414 int32_t digitCount;
1415
Mark Salyzyn961fd022015-04-09 07:18:35 -07001416 RLOGD("dispatchCdmaSmsAck");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001417 memset(&rcsa, 0, sizeof(rcsa));
1418
1419 status = p.readInt32(&t);
1420 rcsa.uErrorClass = (RIL_CDMA_SMS_ErrorClass) t;
1421
1422 status = p.readInt32(&t);
1423 rcsa.uSMSCauseCode = (int) t;
1424
1425 if (status != NO_ERROR) {
1426 goto invalid;
1427 }
1428
1429 startRequest;
1430 appendPrintBuf("%suErrorClass=%d, uTLStatus=%d, ",
1431 printBuf, rcsa.uErrorClass, rcsa.uSMSCauseCode);
1432 closeRequest;
1433
1434 printRequest(pRI->token, pRI->pCI->requestNumber);
1435
Howard Sue32dbfd2015-01-07 15:55:57 +08001436 CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa),pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001437
1438#ifdef MEMSET_FREED
1439 memset(&rcsa, 0, sizeof(rcsa));
1440#endif
1441
1442 return;
1443
1444invalid:
1445 invalidCommandBlock(pRI);
1446 return;
1447}
1448
1449static void
1450dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI) {
1451 int32_t t;
1452 status_t status;
1453 int32_t num;
1454
1455 status = p.readInt32(&num);
1456 if (status != NO_ERROR) {
1457 goto invalid;
1458 }
1459
Ethan Chend6e30652013-08-04 22:49:56 -07001460 {
1461 RIL_GSM_BroadcastSmsConfigInfo gsmBci[num];
1462 RIL_GSM_BroadcastSmsConfigInfo *gsmBciPtrs[num];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001463
Ethan Chend6e30652013-08-04 22:49:56 -07001464 startRequest;
1465 for (int i = 0 ; i < num ; i++ ) {
1466 gsmBciPtrs[i] = &gsmBci[i];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001467
Ethan Chend6e30652013-08-04 22:49:56 -07001468 status = p.readInt32(&t);
1469 gsmBci[i].fromServiceId = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001470
Ethan Chend6e30652013-08-04 22:49:56 -07001471 status = p.readInt32(&t);
1472 gsmBci[i].toServiceId = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001473
Ethan Chend6e30652013-08-04 22:49:56 -07001474 status = p.readInt32(&t);
1475 gsmBci[i].fromCodeScheme = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001476
Ethan Chend6e30652013-08-04 22:49:56 -07001477 status = p.readInt32(&t);
1478 gsmBci[i].toCodeScheme = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001479
Ethan Chend6e30652013-08-04 22:49:56 -07001480 status = p.readInt32(&t);
1481 gsmBci[i].selected = (uint8_t) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001482
Ethan Chend6e30652013-08-04 22:49:56 -07001483 appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId =%d, \
1484 fromCodeScheme=%d, toCodeScheme=%d, selected =%d]", printBuf, i,
1485 gsmBci[i].fromServiceId, gsmBci[i].toServiceId,
1486 gsmBci[i].fromCodeScheme, gsmBci[i].toCodeScheme,
1487 gsmBci[i].selected);
1488 }
1489 closeRequest;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001490
Ethan Chend6e30652013-08-04 22:49:56 -07001491 if (status != NO_ERROR) {
1492 goto invalid;
1493 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001494
Howard Sue32dbfd2015-01-07 15:55:57 +08001495 CALL_ONREQUEST(pRI->pCI->requestNumber,
Ethan Chend6e30652013-08-04 22:49:56 -07001496 gsmBciPtrs,
1497 num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *),
Howard Sue32dbfd2015-01-07 15:55:57 +08001498 pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001499
1500#ifdef MEMSET_FREED
Ethan Chend6e30652013-08-04 22:49:56 -07001501 memset(gsmBci, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo));
1502 memset(gsmBciPtrs, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001503#endif
Ethan Chend6e30652013-08-04 22:49:56 -07001504 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001505
1506 return;
1507
1508invalid:
1509 invalidCommandBlock(pRI);
1510 return;
1511}
1512
1513static void
1514dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI) {
1515 int32_t t;
1516 status_t status;
1517 int32_t num;
1518
1519 status = p.readInt32(&num);
1520 if (status != NO_ERROR) {
1521 goto invalid;
1522 }
1523
Ethan Chend6e30652013-08-04 22:49:56 -07001524 {
1525 RIL_CDMA_BroadcastSmsConfigInfo cdmaBci[num];
1526 RIL_CDMA_BroadcastSmsConfigInfo *cdmaBciPtrs[num];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001527
Ethan Chend6e30652013-08-04 22:49:56 -07001528 startRequest;
1529 for (int i = 0 ; i < num ; i++ ) {
1530 cdmaBciPtrs[i] = &cdmaBci[i];
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001531
Ethan Chend6e30652013-08-04 22:49:56 -07001532 status = p.readInt32(&t);
1533 cdmaBci[i].service_category = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001534
Ethan Chend6e30652013-08-04 22:49:56 -07001535 status = p.readInt32(&t);
1536 cdmaBci[i].language = (int) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001537
Ethan Chend6e30652013-08-04 22:49:56 -07001538 status = p.readInt32(&t);
1539 cdmaBci[i].selected = (uint8_t) t;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001540
Ethan Chend6e30652013-08-04 22:49:56 -07001541 appendPrintBuf("%s [%d: service_category=%d, language =%d, \
1542 entries.bSelected =%d]", printBuf, i, cdmaBci[i].service_category,
1543 cdmaBci[i].language, cdmaBci[i].selected);
1544 }
1545 closeRequest;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001546
Ethan Chend6e30652013-08-04 22:49:56 -07001547 if (status != NO_ERROR) {
1548 goto invalid;
1549 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001550
Howard Sue32dbfd2015-01-07 15:55:57 +08001551 CALL_ONREQUEST(pRI->pCI->requestNumber,
Ethan Chend6e30652013-08-04 22:49:56 -07001552 cdmaBciPtrs,
1553 num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *),
Howard Sue32dbfd2015-01-07 15:55:57 +08001554 pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001555
1556#ifdef MEMSET_FREED
Ethan Chend6e30652013-08-04 22:49:56 -07001557 memset(cdmaBci, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo));
1558 memset(cdmaBciPtrs, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001559#endif
Ethan Chend6e30652013-08-04 22:49:56 -07001560 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001561
1562 return;
1563
1564invalid:
1565 invalidCommandBlock(pRI);
1566 return;
1567}
1568
1569static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI) {
1570 RIL_CDMA_SMS_WriteArgs rcsw;
1571 int32_t t;
1572 uint32_t ut;
1573 uint8_t uct;
1574 status_t status;
1575 int32_t digitCount;
1576
1577 memset(&rcsw, 0, sizeof(rcsw));
1578
1579 status = p.readInt32(&t);
1580 rcsw.status = t;
1581
1582 status = p.readInt32(&t);
1583 rcsw.message.uTeleserviceID = (int) t;
1584
1585 status = p.read(&uct,sizeof(uct));
1586 rcsw.message.bIsServicePresent = (uint8_t) uct;
1587
1588 status = p.readInt32(&t);
1589 rcsw.message.uServicecategory = (int) t;
1590
1591 status = p.readInt32(&t);
1592 rcsw.message.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
1593
1594 status = p.readInt32(&t);
1595 rcsw.message.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
1596
1597 status = p.readInt32(&t);
1598 rcsw.message.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
1599
1600 status = p.readInt32(&t);
1601 rcsw.message.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
1602
1603 status = p.read(&uct,sizeof(uct));
1604 rcsw.message.sAddress.number_of_digits = (uint8_t) uct;
1605
1606 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_ADDRESS_MAX; digitCount ++) {
1607 status = p.read(&uct,sizeof(uct));
1608 rcsw.message.sAddress.digits[digitCount] = (uint8_t) uct;
1609 }
1610
1611 status = p.readInt32(&t);
1612 rcsw.message.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
1613
1614 status = p.read(&uct,sizeof(uct));
1615 rcsw.message.sSubAddress.odd = (uint8_t) uct;
1616
1617 status = p.read(&uct,sizeof(uct));
1618 rcsw.message.sSubAddress.number_of_digits = (uint8_t) uct;
1619
1620 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_SUBADDRESS_MAX; digitCount ++) {
1621 status = p.read(&uct,sizeof(uct));
1622 rcsw.message.sSubAddress.digits[digitCount] = (uint8_t) uct;
1623 }
1624
1625 status = p.readInt32(&t);
1626 rcsw.message.uBearerDataLen = (int) t;
1627
1628 for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_BEARER_DATA_MAX; digitCount ++) {
1629 status = p.read(&uct, sizeof(uct));
1630 rcsw.message.aBearerData[digitCount] = (uint8_t) uct;
1631 }
1632
1633 if (status != NO_ERROR) {
1634 goto invalid;
1635 }
1636
1637 startRequest;
1638 appendPrintBuf("%sstatus=%d, message.uTeleserviceID=%d, message.bIsServicePresent=%d, \
1639 message.uServicecategory=%d, message.sAddress.digit_mode=%d, \
1640 message.sAddress.number_mode=%d, \
1641 message.sAddress.number_type=%d, ",
1642 printBuf, rcsw.status, rcsw.message.uTeleserviceID, rcsw.message.bIsServicePresent,
1643 rcsw.message.uServicecategory, rcsw.message.sAddress.digit_mode,
1644 rcsw.message.sAddress.number_mode,
1645 rcsw.message.sAddress.number_type);
1646 closeRequest;
1647
1648 printRequest(pRI->token, pRI->pCI->requestNumber);
1649
Howard Sue32dbfd2015-01-07 15:55:57 +08001650 CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw),pRI, pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001651
1652#ifdef MEMSET_FREED
1653 memset(&rcsw, 0, sizeof(rcsw));
1654#endif
1655
1656 return;
1657
1658invalid:
1659 invalidCommandBlock(pRI);
1660 return;
1661
1662}
1663
Ethan Chend6e30652013-08-04 22:49:56 -07001664// For backwards compatibility in RIL_REQUEST_SETUP_DATA_CALL.
1665// Version 4 of the RIL interface adds a new PDP type parameter to support
1666// IPv6 and dual-stack PDP contexts. When dealing with a previous version of
1667// RIL, remove the parameter from the request.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001668static void dispatchDataCall(Parcel& p, RequestInfo *pRI) {
Ethan Chend6e30652013-08-04 22:49:56 -07001669 // In RIL v3, REQUEST_SETUP_DATA_CALL takes 6 parameters.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001670 const int numParamsRilV3 = 6;
1671
Ethan Chend6e30652013-08-04 22:49:56 -07001672 // The first bytes of the RIL parcel contain the request number and the
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001673 // serial number - see processCommandBuffer(). Copy them over too.
1674 int pos = p.dataPosition();
1675
1676 int numParams = p.readInt32();
1677 if (s_callbacks.version < 4 && numParams > numParamsRilV3) {
1678 Parcel p2;
1679 p2.appendFrom(&p, 0, pos);
1680 p2.writeInt32(numParamsRilV3);
1681 for(int i = 0; i < numParamsRilV3; i++) {
1682 p2.writeString16(p.readString16());
1683 }
1684 p2.setDataPosition(pos);
1685 dispatchStrings(p2, pRI);
1686 } else {
1687 p.setDataPosition(pos);
1688 dispatchStrings(p, pRI);
1689 }
1690}
1691
1692// For backwards compatibility with RILs that dont support RIL_REQUEST_VOICE_RADIO_TECH.
Ethan Chend6e30652013-08-04 22:49:56 -07001693// When all RILs handle this request, this function can be removed and
1694// the request can be sent directly to the RIL using dispatchVoid.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001695static void dispatchVoiceRadioTech(Parcel& p, RequestInfo *pRI) {
Howard Sue32dbfd2015-01-07 15:55:57 +08001696 RIL_RadioState state = CALL_ONSTATEREQUEST((RIL_SOCKET_ID)pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001697
1698 if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) {
1699 RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1700 }
1701
Ethan Chend6e30652013-08-04 22:49:56 -07001702 // RILs that support RADIO_STATE_ON should support this request.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001703 if (RADIO_STATE_ON == state) {
1704 dispatchVoid(p, pRI);
1705 return;
1706 }
1707
Ethan Chend6e30652013-08-04 22:49:56 -07001708 // For Older RILs, that do not support RADIO_STATE_ON, assume that they
1709 // will not support this new request either and decode Voice Radio Technology
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001710 // from Radio State
1711 voiceRadioTech = decodeVoiceRadioTechnology(state);
1712
1713 if (voiceRadioTech < 0)
1714 RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0);
1715 else
1716 RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &voiceRadioTech, sizeof(int));
1717}
1718
Ethan Chend6e30652013-08-04 22:49:56 -07001719// For backwards compatibility in RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:.
1720// When all RILs handle this request, this function can be removed and
1721// the request can be sent directly to the RIL using dispatchVoid.
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001722static void dispatchCdmaSubscriptionSource(Parcel& p, RequestInfo *pRI) {
Howard Sue32dbfd2015-01-07 15:55:57 +08001723 RIL_RadioState state = CALL_ONSTATEREQUEST((RIL_SOCKET_ID)pRI->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001724
1725 if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) {
1726 RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1727 }
1728
1729 // RILs that support RADIO_STATE_ON should support this request.
1730 if (RADIO_STATE_ON == state) {
1731 dispatchVoid(p, pRI);
1732 return;
1733 }
1734
Ethan Chend6e30652013-08-04 22:49:56 -07001735 // For Older RILs, that do not support RADIO_STATE_ON, assume that they
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001736 // will not support this new request either and decode CDMA Subscription Source
Ethan Chend6e30652013-08-04 22:49:56 -07001737 // from Radio State
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02001738 cdmaSubscriptionSource = decodeCdmaSubscriptionSource(state);
1739
1740 if (cdmaSubscriptionSource < 0)
1741 RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0);
1742 else
1743 RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &cdmaSubscriptionSource, sizeof(int));
1744}
1745
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001746static void dispatchSetInitialAttachApn(Parcel &p, RequestInfo *pRI)
1747{
1748 RIL_InitialAttachApn pf;
1749 int32_t t;
1750 status_t status;
1751
1752 memset(&pf, 0, sizeof(pf));
1753
1754 pf.apn = strdupReadString(p);
1755 pf.protocol = strdupReadString(p);
1756
1757 status = p.readInt32(&t);
1758 pf.authtype = (int) t;
1759
1760 pf.username = strdupReadString(p);
1761 pf.password = strdupReadString(p);
1762
1763 startRequest;
1764 appendPrintBuf("%sapn=%s, protocol=%s, auth_type=%d, username=%s, password=%s",
Andreas Schneidera8d09502015-06-23 18:41:38 +02001765 printBuf, pf.apn, pf.protocol, pf.authtype, pf.username, pf.password);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001766 closeRequest;
1767 printRequest(pRI->token, pRI->pCI->requestNumber);
1768
1769 if (status != NO_ERROR) {
1770 goto invalid;
1771 }
Howard Sue32dbfd2015-01-07 15:55:57 +08001772 CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, pRI->socket_id);
Andrew Jiangca4a9a02014-01-18 18:04:08 -05001773
1774#ifdef MEMSET_FREED
1775 memsetString(pf.apn);
1776 memsetString(pf.protocol);
1777 memsetString(pf.username);
1778 memsetString(pf.password);
1779#endif
1780
1781 free(pf.apn);
1782 free(pf.protocol);
1783 free(pf.username);
1784 free(pf.password);
1785
1786#ifdef MEMSET_FREED
1787 memset(&pf, 0, sizeof(pf));
1788#endif
1789
1790 return;
1791invalid:
1792 invalidCommandBlock(pRI);
1793 return;
1794}
1795
Howard Sue32dbfd2015-01-07 15:55:57 +08001796static void dispatchNVReadItem(Parcel &p, RequestInfo *pRI) {
1797 RIL_NV_ReadItem nvri;
1798 int32_t t;
1799 status_t status;
1800
1801 memset(&nvri, 0, sizeof(nvri));
1802
1803 status = p.readInt32(&t);
1804 nvri.itemID = (RIL_NV_Item) t;
1805
1806 if (status != NO_ERROR) {
1807 goto invalid;
1808 }
1809
1810 startRequest;
1811 appendPrintBuf("%snvri.itemID=%d, ", printBuf, nvri.itemID);
1812 closeRequest;
1813
1814 printRequest(pRI->token, pRI->pCI->requestNumber);
1815
1816 CALL_ONREQUEST(pRI->pCI->requestNumber, &nvri, sizeof(nvri), pRI, pRI->socket_id);
1817
1818#ifdef MEMSET_FREED
1819 memset(&nvri, 0, sizeof(nvri));
1820#endif
1821
1822 return;
1823
1824invalid:
1825 invalidCommandBlock(pRI);
1826 return;
1827}
1828
1829static void dispatchNVWriteItem(Parcel &p, RequestInfo *pRI) {
1830 RIL_NV_WriteItem nvwi;
1831 int32_t t;
1832 status_t status;
1833
1834 memset(&nvwi, 0, sizeof(nvwi));
1835
1836 status = p.readInt32(&t);
1837 nvwi.itemID = (RIL_NV_Item) t;
1838
1839 nvwi.value = strdupReadString(p);
1840
1841 if (status != NO_ERROR || nvwi.value == NULL) {
1842 goto invalid;
1843 }
1844
1845 startRequest;
1846 appendPrintBuf("%snvwi.itemID=%d, value=%s, ", printBuf, nvwi.itemID,
1847 nvwi.value);
1848 closeRequest;
1849
1850 printRequest(pRI->token, pRI->pCI->requestNumber);
1851
1852 CALL_ONREQUEST(pRI->pCI->requestNumber, &nvwi, sizeof(nvwi), pRI, pRI->socket_id);
1853
1854#ifdef MEMSET_FREED
1855 memsetString(nvwi.value);
1856#endif
1857
1858 free(nvwi.value);
1859
1860#ifdef MEMSET_FREED
1861 memset(&nvwi, 0, sizeof(nvwi));
1862#endif
1863
1864 return;
1865
1866invalid:
1867 invalidCommandBlock(pRI);
1868 return;
1869}
1870
1871
1872static void dispatchUiccSubscripton(Parcel &p, RequestInfo *pRI) {
1873 RIL_SelectUiccSub uicc_sub;
1874 status_t status;
1875 int32_t t;
1876 memset(&uicc_sub, 0, sizeof(uicc_sub));
1877
1878 status = p.readInt32(&t);
1879 if (status != NO_ERROR) {
1880 goto invalid;
1881 }
1882 uicc_sub.slot = (int) t;
1883
1884 status = p.readInt32(&t);
1885 if (status != NO_ERROR) {
1886 goto invalid;
1887 }
1888 uicc_sub.app_index = (int) t;
1889
1890 status = p.readInt32(&t);
1891 if (status != NO_ERROR) {
1892 goto invalid;
1893 }
1894 uicc_sub.sub_type = (RIL_SubscriptionType) t;
1895
1896 status = p.readInt32(&t);
1897 if (status != NO_ERROR) {
1898 goto invalid;
1899 }
1900 uicc_sub.act_status = (RIL_UiccSubActStatus) t;
1901
1902 startRequest;
1903 appendPrintBuf("slot=%d, app_index=%d, act_status = %d", uicc_sub.slot, uicc_sub.app_index,
1904 uicc_sub.act_status);
1905 RLOGD("dispatchUiccSubscription, slot=%d, app_index=%d, act_status = %d", uicc_sub.slot,
1906 uicc_sub.app_index, uicc_sub.act_status);
1907 closeRequest;
1908 printRequest(pRI->token, pRI->pCI->requestNumber);
1909
1910 CALL_ONREQUEST(pRI->pCI->requestNumber, &uicc_sub, sizeof(uicc_sub), pRI, pRI->socket_id);
1911
1912#ifdef MEMSET_FREED
1913 memset(&uicc_sub, 0, sizeof(uicc_sub));
1914#endif
1915 return;
1916
1917invalid:
1918 invalidCommandBlock(pRI);
1919 return;
1920}
1921
1922static void dispatchSimAuthentication(Parcel &p, RequestInfo *pRI)
1923{
1924 RIL_SimAuthentication pf;
1925 int32_t t;
1926 status_t status;
1927
1928 memset(&pf, 0, sizeof(pf));
1929
1930 status = p.readInt32(&t);
1931 pf.authContext = (int) t;
1932 pf.authData = strdupReadString(p);
1933 pf.aid = strdupReadString(p);
1934
1935 startRequest;
Andreas Schneidera8d09502015-06-23 18:41:38 +02001936 appendPrintBuf("authContext=%d, authData=%s, aid=%s", pf.authContext, pf.authData, pf.aid);
Howard Sue32dbfd2015-01-07 15:55:57 +08001937 closeRequest;
1938 printRequest(pRI->token, pRI->pCI->requestNumber);
1939
1940 if (status != NO_ERROR) {
1941 goto invalid;
1942 }
1943 CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, pRI->socket_id);
1944
1945#ifdef MEMSET_FREED
1946 memsetString(pf.authData);
1947 memsetString(pf.aid);
1948#endif
1949
1950 free(pf.authData);
1951 free(pf.aid);
1952
1953#ifdef MEMSET_FREED
1954 memset(&pf, 0, sizeof(pf));
1955#endif
1956
1957 return;
1958invalid:
1959 invalidCommandBlock(pRI);
1960 return;
1961}
1962
1963static void dispatchDataProfile(Parcel &p, RequestInfo *pRI) {
1964 int32_t t;
1965 status_t status;
1966 int32_t num;
1967
1968 status = p.readInt32(&num);
1969 if (status != NO_ERROR) {
1970 goto invalid;
1971 }
1972
1973 {
1974 RIL_DataProfileInfo dataProfiles[num];
1975 RIL_DataProfileInfo *dataProfilePtrs[num];
1976
1977 startRequest;
1978 for (int i = 0 ; i < num ; i++ ) {
1979 dataProfilePtrs[i] = &dataProfiles[i];
1980
1981 status = p.readInt32(&t);
1982 dataProfiles[i].profileId = (int) t;
1983
1984 dataProfiles[i].apn = strdupReadString(p);
1985 dataProfiles[i].protocol = strdupReadString(p);
1986 status = p.readInt32(&t);
1987 dataProfiles[i].authType = (int) t;
1988
1989 dataProfiles[i].user = strdupReadString(p);
1990 dataProfiles[i].password = strdupReadString(p);
1991
1992 status = p.readInt32(&t);
1993 dataProfiles[i].type = (int) t;
1994
1995 status = p.readInt32(&t);
1996 dataProfiles[i].maxConnsTime = (int) t;
1997 status = p.readInt32(&t);
1998 dataProfiles[i].maxConns = (int) t;
1999 status = p.readInt32(&t);
2000 dataProfiles[i].waitTime = (int) t;
2001
2002 status = p.readInt32(&t);
2003 dataProfiles[i].enabled = (int) t;
2004
2005 appendPrintBuf("%s [%d: profileId=%d, apn =%s, protocol =%s, authType =%d, \
2006 user =%s, password =%s, type =%d, maxConnsTime =%d, maxConns =%d, \
2007 waitTime =%d, enabled =%d]", printBuf, i, dataProfiles[i].profileId,
2008 dataProfiles[i].apn, dataProfiles[i].protocol, dataProfiles[i].authType,
2009 dataProfiles[i].user, dataProfiles[i].password, dataProfiles[i].type,
2010 dataProfiles[i].maxConnsTime, dataProfiles[i].maxConns,
2011 dataProfiles[i].waitTime, dataProfiles[i].enabled);
2012 }
2013 closeRequest;
2014 printRequest(pRI->token, pRI->pCI->requestNumber);
2015
2016 if (status != NO_ERROR) {
2017 goto invalid;
2018 }
2019 CALL_ONREQUEST(pRI->pCI->requestNumber,
2020 dataProfilePtrs,
2021 num * sizeof(RIL_DataProfileInfo *),
2022 pRI, pRI->socket_id);
2023
2024#ifdef MEMSET_FREED
2025 memset(dataProfiles, 0, num * sizeof(RIL_DataProfileInfo));
2026 memset(dataProfilePtrs, 0, num * sizeof(RIL_DataProfileInfo *));
2027#endif
2028 }
2029
2030 return;
2031
2032invalid:
2033 invalidCommandBlock(pRI);
2034 return;
2035}
2036
Howard Subd82ef12015-04-12 10:25:05 +02002037static void dispatchRadioCapability(Parcel &p, RequestInfo *pRI){
2038 RIL_RadioCapability rc;
2039 int32_t t;
2040 status_t status;
2041
2042 memset (&rc, 0, sizeof(RIL_RadioCapability));
2043
2044 status = p.readInt32(&t);
2045 rc.version = (int)t;
2046 if (status != NO_ERROR) {
2047 goto invalid;
2048 }
2049
2050 status = p.readInt32(&t);
2051 rc.session= (int)t;
2052 if (status != NO_ERROR) {
2053 goto invalid;
2054 }
2055
2056 status = p.readInt32(&t);
2057 rc.phase= (int)t;
2058 if (status != NO_ERROR) {
2059 goto invalid;
2060 }
2061
2062 status = p.readInt32(&t);
2063 rc.rat = (int)t;
2064 if (status != NO_ERROR) {
2065 goto invalid;
2066 }
2067
2068 status = readStringFromParcelInplace(p, rc.logicalModemUuid, sizeof(rc.logicalModemUuid));
2069 if (status != NO_ERROR) {
2070 goto invalid;
2071 }
2072
2073 status = p.readInt32(&t);
2074 rc.status = (int)t;
2075
2076 if (status != NO_ERROR) {
2077 goto invalid;
2078 }
2079
2080 startRequest;
2081 appendPrintBuf("%s [version:%d, session:%d, phase:%d, rat:%d, \
Andreas Schneidera8d09502015-06-23 18:41:38 +02002082 logicalModemUuid:%s, status:%d", printBuf, rc.version, rc.session,
2083 rc.phase, rc.rat, rc.logicalModemUuid, rc.status);
Howard Subd82ef12015-04-12 10:25:05 +02002084
2085 closeRequest;
2086 printRequest(pRI->token, pRI->pCI->requestNumber);
2087
2088 CALL_ONREQUEST(pRI->pCI->requestNumber,
2089 &rc,
2090 sizeof(RIL_RadioCapability),
2091 pRI, pRI->socket_id);
2092 return;
2093invalid:
2094 invalidCommandBlock(pRI);
2095 return;
2096}
2097
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002098static int
2099blockingWrite(int fd, const void *buffer, size_t len) {
2100 size_t writeOffset = 0;
2101 const uint8_t *toWrite;
2102
2103 toWrite = (const uint8_t *)buffer;
2104
2105 while (writeOffset < len) {
2106 ssize_t written;
2107 do {
2108 written = write (fd, toWrite + writeOffset,
2109 len - writeOffset);
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002110 } while (written < 0 && ((errno == EINTR) || (errno == EAGAIN)));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002111
2112 if (written >= 0) {
2113 writeOffset += written;
2114 } else { // written < 0
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002115 RLOGE ("RIL Response: unexpected error on write errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002116 close(fd);
2117 return -1;
2118 }
2119 }
Dheeraj Shettycc231012014-07-02 21:27:57 +02002120 RLOGE("RIL Response bytes written:%d", writeOffset);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002121 return 0;
2122}
2123
2124static int
Howard Sue32dbfd2015-01-07 15:55:57 +08002125sendResponseRaw (const void *data, size_t dataSize, RIL_SOCKET_ID socket_id) {
2126 int fd = s_ril_param_socket.fdCommand;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002127 int ret;
2128 uint32_t header;
Howard Sue32dbfd2015-01-07 15:55:57 +08002129 pthread_mutex_t * writeMutexHook = &s_writeMutex;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002130
Howard Sue32dbfd2015-01-07 15:55:57 +08002131 RLOGE("Send Response to %s", rilSocketIdToString(socket_id));
2132
2133#if (SIM_COUNT >= 2)
2134 if (socket_id == RIL_SOCKET_2) {
2135 fd = s_ril_param_socket2.fdCommand;
2136 writeMutexHook = &s_writeMutex_socket2;
2137 }
2138#if (SIM_COUNT >= 3)
2139 else if (socket_id == RIL_SOCKET_3) {
2140 fd = s_ril_param_socket3.fdCommand;
2141 writeMutexHook = &s_writeMutex_socket3;
2142 }
2143#endif
2144#if (SIM_COUNT >= 4)
2145 else if (socket_id == RIL_SOCKET_4) {
2146 fd = s_ril_param_socket4.fdCommand;
2147 writeMutexHook = &s_writeMutex_socket4;
2148 }
2149#endif
2150#endif
2151 if (fd < 0) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002152 return -1;
2153 }
2154
Howard Subd82ef12015-04-12 10:25:05 +02002155 if (dataSize > MAX_COMMAND_BYTES) {
2156 RLOGE("RIL: packet larger than %u (%u)",
2157 MAX_COMMAND_BYTES, (unsigned int )dataSize);
2158
2159 return -1;
2160 }
2161
Howard Sue32dbfd2015-01-07 15:55:57 +08002162 pthread_mutex_lock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002163
2164 header = htonl(dataSize);
2165
2166 ret = blockingWrite(fd, (void *)&header, sizeof(header));
2167
2168 if (ret < 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002169 pthread_mutex_unlock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002170 return ret;
2171 }
2172
2173 ret = blockingWrite(fd, data, dataSize);
2174
2175 if (ret < 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002176 pthread_mutex_unlock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002177 return ret;
2178 }
2179
Howard Sue32dbfd2015-01-07 15:55:57 +08002180 pthread_mutex_unlock(writeMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002181
2182 return 0;
2183}
2184
2185static int
Howard Sue32dbfd2015-01-07 15:55:57 +08002186sendResponse (Parcel &p, RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002187 printResponse;
Howard Sue32dbfd2015-01-07 15:55:57 +08002188 return sendResponseRaw(p.data(), p.dataSize(), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002189}
2190
Howard Sue32dbfd2015-01-07 15:55:57 +08002191/** response is an int* pointing to an array of ints */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002192
2193static int
2194responseInts(Parcel &p, void *response, size_t responselen) {
2195 int numInts;
2196
2197 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002198 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002199 return RIL_ERRNO_INVALID_RESPONSE;
2200 }
2201 if (responselen % sizeof(int) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002202 RLOGE("responseInts: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002203 (int)responselen, (int)sizeof(int));
2204 return RIL_ERRNO_INVALID_RESPONSE;
2205 }
2206
2207 int *p_int = (int *) response;
2208
Howard Sue32dbfd2015-01-07 15:55:57 +08002209 numInts = responselen / sizeof(int);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002210 p.writeInt32 (numInts);
2211
2212 /* each int*/
2213 startResponse;
2214 for (int i = 0 ; i < numInts ; i++) {
2215 appendPrintBuf("%s%d,", printBuf, p_int[i]);
2216 p.writeInt32(p_int[i]);
2217 }
2218 removeLastChar;
2219 closeResponse;
2220
2221 return 0;
2222}
2223
Daniel Hillenbrandd0b84162015-04-12 11:53:23 +02002224static int
2225responseIntsGetPreferredNetworkType(Parcel &p, void *response, size_t responselen) {
2226 int numInts;
2227
2228 if (response == NULL && responselen != 0) {
2229 RLOGE("invalid response: NULL");
2230 return RIL_ERRNO_INVALID_RESPONSE;
2231 }
2232 if (responselen % sizeof(int) != 0) {
2233 RLOGE("responseInts: invalid response length %d expected multiple of %d\n",
2234 (int)responselen, (int)sizeof(int));
2235 return RIL_ERRNO_INVALID_RESPONSE;
2236 }
2237
2238 int *p_int = (int *) response;
2239
2240 numInts = responselen / sizeof(int);
2241 p.writeInt32 (numInts);
2242
2243 /* each int*/
2244 startResponse;
2245 for (int i = 0 ; i < numInts ; i++) {
2246 if (i == 0 && p_int[0] == 7) {
2247 RLOGD("REQUEST_GET_PREFERRED_NETWORK_TYPE: NETWORK_MODE_GLOBAL => NETWORK_MODE_WCDMA_PREF");
2248 p_int[0] = 0;
2249 }
2250 appendPrintBuf("%s%d,", printBuf, p_int[i]);
2251 p.writeInt32(p_int[i]);
2252 }
2253 removeLastChar;
2254 closeResponse;
2255
2256 return 0;
2257}
2258
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002259/** response is a char **, pointing to an array of char *'s
2260 The parcel will begin with the version */
2261static int responseStringsWithVersion(int version, Parcel &p, void *response, size_t responselen) {
2262 p.writeInt32(version);
2263 return responseStrings(p, response, responselen);
2264}
2265
2266/** response is a char **, pointing to an array of char *'s */
2267static int responseStrings(Parcel &p, void *response, size_t responselen) {
2268 return responseStrings(p, response, responselen, false);
2269}
2270
Utkarsh Guptaf7a63e52015-05-10 16:53:37 +05302271static int responseStringsNetworks(Parcel &p, void *response, size_t responselen) {
2272 return responseStrings(p, response, responselen, true);
2273}
2274
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002275/** response is a char **, pointing to an array of char *'s */
2276static int responseStrings(Parcel &p, void *response, size_t responselen, bool network_search) {
2277 int numStrings;
2278
2279 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002280 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002281 return RIL_ERRNO_INVALID_RESPONSE;
2282 }
2283 if (responselen % sizeof(char *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002284 RLOGE("responseStrings: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002285 (int)responselen, (int)sizeof(char *));
2286 return RIL_ERRNO_INVALID_RESPONSE;
2287 }
2288
2289 if (response == NULL) {
2290 p.writeInt32 (0);
2291 } else {
2292 char **p_cur = (char **) response;
2293
2294 numStrings = responselen / sizeof(char *);
Utkarsh Guptaf7a63e52015-05-10 16:53:37 +05302295 if (network_search) {
2296 p.writeInt32 ((numStrings / 5) * 4);
2297 } else {
2298 p.writeInt32 (numStrings);
2299 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002300
2301 /* each string*/
2302 startResponse;
2303 for (int i = 0 ; i < numStrings ; i++) {
NBruderman72edd422015-06-08 15:54:55 +03002304 if (network_search && ((i + 1) % 5 == 0))
Utkarsh Guptaf7a63e52015-05-10 16:53:37 +05302305 continue;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002306 appendPrintBuf("%s%s,", printBuf, (char*)p_cur[i]);
2307 writeStringToParcel (p, p_cur[i]);
2308 }
2309 removeLastChar;
2310 closeResponse;
2311 }
2312 return 0;
2313}
2314
Howard Subd82ef12015-04-12 10:25:05 +02002315
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002316/**
2317 * NULL strings are accepted
2318 * FIXME currently ignores responselen
2319 */
2320static int responseString(Parcel &p, void *response, size_t responselen) {
2321 /* one string only */
2322 startResponse;
2323 appendPrintBuf("%s%s", printBuf, (char*)response);
2324 closeResponse;
2325
2326 writeStringToParcel(p, (const char *)response);
2327
2328 return 0;
2329}
2330
2331static int responseVoid(Parcel &p, void *response, size_t responselen) {
2332 startResponse;
2333 removeLastChar;
2334 return 0;
2335}
2336
2337static int responseCallList(Parcel &p, void *response, size_t responselen) {
2338 int num;
2339
2340 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002341 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002342 return RIL_ERRNO_INVALID_RESPONSE;
2343 }
2344
2345 if (responselen % sizeof (RIL_Call *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002346 RLOGE("responseCallList: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002347 (int)responselen, (int)sizeof (RIL_Call *));
2348 return RIL_ERRNO_INVALID_RESPONSE;
2349 }
2350
2351 startResponse;
2352 /* number of call info's */
2353 num = responselen / sizeof(RIL_Call *);
2354 p.writeInt32(num);
2355
2356 for (int i = 0 ; i < num ; i++) {
2357 RIL_Call *p_cur = ((RIL_Call **) response)[i];
2358 /* each call info */
2359 p.writeInt32(p_cur->state);
2360 p.writeInt32(p_cur->index);
2361 p.writeInt32(p_cur->toa);
2362 p.writeInt32(p_cur->isMpty);
2363 p.writeInt32(p_cur->isMT);
2364 p.writeInt32(p_cur->als);
2365 p.writeInt32(p_cur->isVoice);
Andreas Schneider29472682015-01-01 19:00:04 +01002366
Christopher N. Hesse7bf409e2015-06-26 14:53:56 +02002367#if defined(MODEM_TYPE_XMM7260) || defined(MODEM_TYPE_M7450)
Andreas Schneider29472682015-01-01 19:00:04 +01002368 p.writeInt32(p_cur->isVideo);
2369
2370 /* Pass CallDetails */
2371 p.writeInt32(0);
2372 p.writeInt32(0);
2373 writeStringToParcel(p, "");
2374#endif
2375
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002376 p.writeInt32(p_cur->isVoicePrivacy);
2377 writeStringToParcel(p, p_cur->number);
2378 p.writeInt32(p_cur->numberPresentation);
2379 writeStringToParcel(p, p_cur->name);
2380 p.writeInt32(p_cur->namePresentation);
2381 // Remove when partners upgrade to version 3
2382 if ((s_callbacks.version < 3) || (p_cur->uusInfo == NULL || p_cur->uusInfo->uusData == NULL)) {
2383 p.writeInt32(0); /* UUS Information is absent */
2384 } else {
2385 RIL_UUS_Info *uusInfo = p_cur->uusInfo;
2386 p.writeInt32(1); /* UUS Information is present */
2387 p.writeInt32(uusInfo->uusType);
2388 p.writeInt32(uusInfo->uusDcs);
2389 p.writeInt32(uusInfo->uusLength);
2390 p.write(uusInfo->uusData, uusInfo->uusLength);
2391 }
2392 appendPrintBuf("%s[id=%d,%s,toa=%d,",
2393 printBuf,
2394 p_cur->index,
2395 callStateToString(p_cur->state),
2396 p_cur->toa);
2397 appendPrintBuf("%s%s,%s,als=%d,%s,%s,",
2398 printBuf,
2399 (p_cur->isMpty)?"conf":"norm",
2400 (p_cur->isMT)?"mt":"mo",
2401 p_cur->als,
2402 (p_cur->isVoice)?"voc":"nonvoc",
2403 (p_cur->isVoicePrivacy)?"evp":"noevp");
Christopher N. Hesse7bf409e2015-06-26 14:53:56 +02002404#if defined(MODEM_TYPE_XMM7260) || defined(MODEM_TYPE_M7450)
Andreas Schneider29472682015-01-01 19:00:04 +01002405 appendPrintBuf("%s,%s,",
2406 printBuf,
2407 (p_cur->isVideo) ? "vid" : "novid");
2408#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002409 appendPrintBuf("%s%s,cli=%d,name='%s',%d]",
2410 printBuf,
2411 p_cur->number,
2412 p_cur->numberPresentation,
2413 p_cur->name,
2414 p_cur->namePresentation);
2415 }
2416 removeLastChar;
2417 closeResponse;
2418
2419 return 0;
2420}
2421
2422static int responseSMS(Parcel &p, void *response, size_t responselen) {
2423 if (response == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002424 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002425 return RIL_ERRNO_INVALID_RESPONSE;
2426 }
2427
2428 if (responselen != sizeof (RIL_SMS_Response) ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002429 RLOGE("invalid response length %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002430 (int)responselen, (int)sizeof (RIL_SMS_Response));
2431 return RIL_ERRNO_INVALID_RESPONSE;
2432 }
2433
2434 RIL_SMS_Response *p_cur = (RIL_SMS_Response *) response;
2435
2436 p.writeInt32(p_cur->messageRef);
2437 writeStringToParcel(p, p_cur->ackPDU);
2438 p.writeInt32(p_cur->errorCode);
2439
2440 startResponse;
2441 appendPrintBuf("%s%d,%s,%d", printBuf, p_cur->messageRef,
2442 (char*)p_cur->ackPDU, p_cur->errorCode);
2443 closeResponse;
2444
2445 return 0;
2446}
2447
2448static int responseDataCallListV4(Parcel &p, void *response, size_t responselen)
2449{
2450 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002451 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002452 return RIL_ERRNO_INVALID_RESPONSE;
2453 }
2454
2455 if (responselen % sizeof(RIL_Data_Call_Response_v4) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002456 RLOGE("responseDataCallListV4: invalid response length %d expected multiple of %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002457 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v4));
2458 return RIL_ERRNO_INVALID_RESPONSE;
2459 }
2460
Howard Sue32dbfd2015-01-07 15:55:57 +08002461 // Write version
2462 p.writeInt32(4);
2463
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002464 int num = responselen / sizeof(RIL_Data_Call_Response_v4);
2465 p.writeInt32(num);
2466
2467 RIL_Data_Call_Response_v4 *p_cur = (RIL_Data_Call_Response_v4 *) response;
2468 startResponse;
2469 int i;
2470 for (i = 0; i < num; i++) {
2471 p.writeInt32(p_cur[i].cid);
2472 p.writeInt32(p_cur[i].active);
2473 writeStringToParcel(p, p_cur[i].type);
2474 // apn is not used, so don't send.
2475 writeStringToParcel(p, p_cur[i].address);
2476 appendPrintBuf("%s[cid=%d,%s,%s,%s],", printBuf,
2477 p_cur[i].cid,
2478 (p_cur[i].active==0)?"down":"up",
2479 (char*)p_cur[i].type,
2480 (char*)p_cur[i].address);
2481 }
2482 removeLastChar;
2483 closeResponse;
2484
2485 return 0;
2486}
2487
Howard Sue32dbfd2015-01-07 15:55:57 +08002488static int responseDataCallListV6(Parcel &p, void *response, size_t responselen)
2489{
2490 if (response == NULL && responselen != 0) {
2491 RLOGE("invalid response: NULL");
2492 return RIL_ERRNO_INVALID_RESPONSE;
2493 }
2494
2495 if (responselen % sizeof(RIL_Data_Call_Response_v6) != 0) {
2496 RLOGE("responseDataCallListV6: invalid response length %d expected multiple of %d",
2497 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v6));
2498 return RIL_ERRNO_INVALID_RESPONSE;
2499 }
2500
2501 // Write version
2502 p.writeInt32(6);
2503
2504 int num = responselen / sizeof(RIL_Data_Call_Response_v6);
2505 p.writeInt32(num);
2506
2507 RIL_Data_Call_Response_v6 *p_cur = (RIL_Data_Call_Response_v6 *) response;
2508 startResponse;
2509 int i;
2510 for (i = 0; i < num; i++) {
2511 p.writeInt32((int)p_cur[i].status);
2512 p.writeInt32(p_cur[i].suggestedRetryTime);
2513 p.writeInt32(p_cur[i].cid);
2514 p.writeInt32(p_cur[i].active);
2515 writeStringToParcel(p, p_cur[i].type);
2516 writeStringToParcel(p, p_cur[i].ifname);
2517 writeStringToParcel(p, p_cur[i].addresses);
2518 writeStringToParcel(p, p_cur[i].dnses);
2519 writeStringToParcel(p, p_cur[i].addresses);
2520 appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s],", printBuf,
2521 p_cur[i].status,
2522 p_cur[i].suggestedRetryTime,
2523 p_cur[i].cid,
2524 (p_cur[i].active==0)?"down":"up",
2525 (char*)p_cur[i].type,
2526 (char*)p_cur[i].ifname,
2527 (char*)p_cur[i].addresses,
2528 (char*)p_cur[i].dnses,
2529 (char*)p_cur[i].addresses);
2530 }
2531 removeLastChar;
2532 closeResponse;
2533
2534 return 0;
2535}
2536
Howard Subd82ef12015-04-12 10:25:05 +02002537static int responseDataCallListV9(Parcel &p, void *response, size_t responselen)
2538{
2539 if (response == NULL && responselen != 0) {
2540 RLOGE("invalid response: NULL");
2541 return RIL_ERRNO_INVALID_RESPONSE;
2542 }
2543
2544 if (responselen % sizeof(RIL_Data_Call_Response_v9) != 0) {
2545 RLOGE("responseDataCallListV9: invalid response length %d expected multiple of %d",
2546 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v9));
2547 return RIL_ERRNO_INVALID_RESPONSE;
2548 }
2549
2550 // Write version
2551 p.writeInt32(10);
2552
2553 int num = responselen / sizeof(RIL_Data_Call_Response_v9);
2554 p.writeInt32(num);
2555
2556 RIL_Data_Call_Response_v9 *p_cur = (RIL_Data_Call_Response_v9 *) response;
2557 startResponse;
2558 int i;
2559 for (i = 0; i < num; i++) {
2560 p.writeInt32((int)p_cur[i].status);
2561 p.writeInt32(p_cur[i].suggestedRetryTime);
2562 p.writeInt32(p_cur[i].cid);
2563 p.writeInt32(p_cur[i].active);
2564 writeStringToParcel(p, p_cur[i].type);
2565 writeStringToParcel(p, p_cur[i].ifname);
2566 writeStringToParcel(p, p_cur[i].addresses);
2567 writeStringToParcel(p, p_cur[i].dnses);
2568 writeStringToParcel(p, p_cur[i].gateways);
2569 writeStringToParcel(p, p_cur[i].pcscf);
2570 appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s],", printBuf,
2571 p_cur[i].status,
2572 p_cur[i].suggestedRetryTime,
2573 p_cur[i].cid,
2574 (p_cur[i].active==0)?"down":"up",
2575 (char*)p_cur[i].type,
2576 (char*)p_cur[i].ifname,
2577 (char*)p_cur[i].addresses,
2578 (char*)p_cur[i].dnses,
2579 (char*)p_cur[i].gateways,
2580 (char*)p_cur[i].pcscf);
2581 }
2582 removeLastChar;
2583 closeResponse;
2584
2585 return 0;
2586}
2587
2588
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002589static int responseDataCallList(Parcel &p, void *response, size_t responselen)
2590{
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002591 if (s_callbacks.version < 5) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002592 RLOGD("responseDataCallList: v4");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002593 return responseDataCallListV4(p, response, responselen);
Howard Subd82ef12015-04-12 10:25:05 +02002594 } else if (responselen % sizeof(RIL_Data_Call_Response_v6) == 0) {
2595 return responseDataCallListV6(p, response, responselen);
2596 } else if (responselen % sizeof(RIL_Data_Call_Response_v9) == 0) {
2597 return responseDataCallListV9(p, response, responselen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002598 } else {
2599 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002600 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002601 return RIL_ERRNO_INVALID_RESPONSE;
2602 }
2603
Howard Subd82ef12015-04-12 10:25:05 +02002604 if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) {
2605 RLOGE("invalid response length %d expected multiple of %d",
2606 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v11));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002607 return RIL_ERRNO_INVALID_RESPONSE;
2608 }
2609
Howard Sue32dbfd2015-01-07 15:55:57 +08002610 // Write version
Howard Subd82ef12015-04-12 10:25:05 +02002611 p.writeInt32(11);
Howard Sue32dbfd2015-01-07 15:55:57 +08002612
Howard Subd82ef12015-04-12 10:25:05 +02002613 int num = responselen / sizeof(RIL_Data_Call_Response_v11);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002614 p.writeInt32(num);
2615
Howard Subd82ef12015-04-12 10:25:05 +02002616 RIL_Data_Call_Response_v11 *p_cur = (RIL_Data_Call_Response_v11 *) response;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002617 startResponse;
2618 int i;
2619 for (i = 0; i < num; i++) {
2620 p.writeInt32((int)p_cur[i].status);
2621 p.writeInt32(p_cur[i].suggestedRetryTime);
2622 p.writeInt32(p_cur[i].cid);
2623 p.writeInt32(p_cur[i].active);
2624 writeStringToParcel(p, p_cur[i].type);
2625 writeStringToParcel(p, p_cur[i].ifname);
2626 writeStringToParcel(p, p_cur[i].addresses);
2627 writeStringToParcel(p, p_cur[i].dnses);
Howard Sue32dbfd2015-01-07 15:55:57 +08002628 writeStringToParcel(p, p_cur[i].gateways);
2629 writeStringToParcel(p, p_cur[i].pcscf);
Howard Subd82ef12015-04-12 10:25:05 +02002630 p.writeInt32(p_cur[i].mtu);
2631 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 +02002632 p_cur[i].status,
2633 p_cur[i].suggestedRetryTime,
2634 p_cur[i].cid,
2635 (p_cur[i].active==0)?"down":"up",
2636 (char*)p_cur[i].type,
2637 (char*)p_cur[i].ifname,
2638 (char*)p_cur[i].addresses,
2639 (char*)p_cur[i].dnses,
Howard Sue32dbfd2015-01-07 15:55:57 +08002640 (char*)p_cur[i].gateways,
Howard Subd82ef12015-04-12 10:25:05 +02002641 (char*)p_cur[i].pcscf,
2642 p_cur[i].mtu);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002643 }
2644 removeLastChar;
2645 closeResponse;
2646 }
2647
2648 return 0;
2649}
2650
2651static int responseSetupDataCall(Parcel &p, void *response, size_t responselen)
2652{
2653 if (s_callbacks.version < 5) {
2654 return responseStringsWithVersion(s_callbacks.version, p, response, responselen);
2655 } else {
2656 return responseDataCallList(p, response, responselen);
2657 }
2658}
2659
2660static int responseRaw(Parcel &p, void *response, size_t responselen) {
2661 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002662 RLOGE("invalid response: NULL with responselen != 0");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002663 return RIL_ERRNO_INVALID_RESPONSE;
2664 }
2665
2666 // The java code reads -1 size as null byte array
2667 if (response == NULL) {
2668 p.writeInt32(-1);
2669 } else {
2670 p.writeInt32(responselen);
2671 p.write(response, responselen);
2672 }
2673
2674 return 0;
2675}
2676
2677
2678static int responseSIM_IO(Parcel &p, void *response, size_t responselen) {
2679 if (response == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002680 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002681 return RIL_ERRNO_INVALID_RESPONSE;
2682 }
2683
2684 if (responselen != sizeof (RIL_SIM_IO_Response) ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002685 RLOGE("invalid response length was %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002686 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
2687 return RIL_ERRNO_INVALID_RESPONSE;
2688 }
2689
2690 RIL_SIM_IO_Response *p_cur = (RIL_SIM_IO_Response *) response;
2691 p.writeInt32(p_cur->sw1);
2692 p.writeInt32(p_cur->sw2);
2693 writeStringToParcel(p, p_cur->simResponse);
2694
2695 startResponse;
2696 appendPrintBuf("%ssw1=0x%X,sw2=0x%X,%s", printBuf, p_cur->sw1, p_cur->sw2,
2697 (char*)p_cur->simResponse);
2698 closeResponse;
2699
2700
2701 return 0;
2702}
2703
2704static int responseCallForwards(Parcel &p, void *response, size_t responselen) {
2705 int num;
2706
2707 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002708 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002709 return RIL_ERRNO_INVALID_RESPONSE;
2710 }
2711
2712 if (responselen % sizeof(RIL_CallForwardInfo *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002713 RLOGE("responseCallForwards: invalid response length %d expected multiple of %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002714 (int)responselen, (int)sizeof(RIL_CallForwardInfo *));
2715 return RIL_ERRNO_INVALID_RESPONSE;
2716 }
2717
2718 /* number of call info's */
2719 num = responselen / sizeof(RIL_CallForwardInfo *);
2720 p.writeInt32(num);
2721
2722 startResponse;
2723 for (int i = 0 ; i < num ; i++) {
2724 RIL_CallForwardInfo *p_cur = ((RIL_CallForwardInfo **) response)[i];
2725
2726 p.writeInt32(p_cur->status);
2727 p.writeInt32(p_cur->reason);
2728 p.writeInt32(p_cur->serviceClass);
2729 p.writeInt32(p_cur->toa);
2730 writeStringToParcel(p, p_cur->number);
2731 p.writeInt32(p_cur->timeSeconds);
2732 appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
2733 (p_cur->status==1)?"enable":"disable",
2734 p_cur->reason, p_cur->serviceClass, p_cur->toa,
2735 (char*)p_cur->number,
2736 p_cur->timeSeconds);
2737 }
2738 removeLastChar;
2739 closeResponse;
2740
2741 return 0;
2742}
2743
2744static int responseSsn(Parcel &p, void *response, size_t responselen) {
2745 if (response == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002746 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002747 return RIL_ERRNO_INVALID_RESPONSE;
2748 }
2749
2750 if (responselen != sizeof(RIL_SuppSvcNotification)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002751 RLOGE("invalid response length was %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002752 (int)responselen, (int)sizeof (RIL_SuppSvcNotification));
2753 return RIL_ERRNO_INVALID_RESPONSE;
2754 }
2755
2756 RIL_SuppSvcNotification *p_cur = (RIL_SuppSvcNotification *) response;
2757 p.writeInt32(p_cur->notificationType);
2758 p.writeInt32(p_cur->code);
2759 p.writeInt32(p_cur->index);
2760 p.writeInt32(p_cur->type);
2761 writeStringToParcel(p, p_cur->number);
2762
2763 startResponse;
2764 appendPrintBuf("%s%s,code=%d,id=%d,type=%d,%s", printBuf,
2765 (p_cur->notificationType==0)?"mo":"mt",
2766 p_cur->code, p_cur->index, p_cur->type,
2767 (char*)p_cur->number);
2768 closeResponse;
2769
2770 return 0;
2771}
2772
2773static int responseCellList(Parcel &p, void *response, size_t responselen) {
2774 int num;
2775
2776 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002777 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002778 return RIL_ERRNO_INVALID_RESPONSE;
2779 }
2780
2781 if (responselen % sizeof (RIL_NeighboringCell *) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002782 RLOGE("responseCellList: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002783 (int)responselen, (int)sizeof (RIL_NeighboringCell *));
2784 return RIL_ERRNO_INVALID_RESPONSE;
2785 }
2786
2787 startResponse;
2788 /* number of records */
2789 num = responselen / sizeof(RIL_NeighboringCell *);
2790 p.writeInt32(num);
2791
2792 for (int i = 0 ; i < num ; i++) {
2793 RIL_NeighboringCell *p_cur = ((RIL_NeighboringCell **) response)[i];
2794
2795 p.writeInt32(p_cur->rssi);
2796 writeStringToParcel (p, p_cur->cid);
2797
2798 appendPrintBuf("%s[cid=%s,rssi=%d],", printBuf,
2799 p_cur->cid, p_cur->rssi);
2800 }
2801 removeLastChar;
2802 closeResponse;
2803
2804 return 0;
2805}
2806
2807/**
2808 * Marshall the signalInfoRecord into the parcel if it exists.
2809 */
2810static void marshallSignalInfoRecord(Parcel &p,
2811 RIL_CDMA_SignalInfoRecord &p_signalInfoRecord) {
2812 p.writeInt32(p_signalInfoRecord.isPresent);
2813 p.writeInt32(p_signalInfoRecord.signalType);
2814 p.writeInt32(p_signalInfoRecord.alertPitch);
2815 p.writeInt32(p_signalInfoRecord.signal);
2816}
2817
2818static int responseCdmaInformationRecords(Parcel &p,
2819 void *response, size_t responselen) {
2820 int num;
2821 char* string8 = NULL;
2822 int buffer_lenght;
2823 RIL_CDMA_InformationRecord *infoRec;
2824
2825 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002826 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002827 return RIL_ERRNO_INVALID_RESPONSE;
2828 }
2829
2830 if (responselen != sizeof (RIL_CDMA_InformationRecords)) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002831 RLOGE("responseCdmaInformationRecords: invalid response length %d expected multiple of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002832 (int)responselen, (int)sizeof (RIL_CDMA_InformationRecords *));
2833 return RIL_ERRNO_INVALID_RESPONSE;
2834 }
2835
2836 RIL_CDMA_InformationRecords *p_cur =
2837 (RIL_CDMA_InformationRecords *) response;
2838 num = MIN(p_cur->numberOfInfoRecs, RIL_CDMA_MAX_NUMBER_OF_INFO_RECS);
2839
2840 startResponse;
2841 p.writeInt32(num);
2842
2843 for (int i = 0 ; i < num ; i++) {
2844 infoRec = &p_cur->infoRec[i];
2845 p.writeInt32(infoRec->name);
2846 switch (infoRec->name) {
2847 case RIL_CDMA_DISPLAY_INFO_REC:
2848 case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
2849 if (infoRec->rec.display.alpha_len >
2850 CDMA_ALPHA_INFO_BUFFER_LENGTH) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002851 RLOGE("invalid display info response length %d \
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002852 expected not more than %d\n",
2853 (int)infoRec->rec.display.alpha_len,
2854 CDMA_ALPHA_INFO_BUFFER_LENGTH);
2855 return RIL_ERRNO_INVALID_RESPONSE;
2856 }
2857 string8 = (char*) malloc((infoRec->rec.display.alpha_len + 1)
2858 * sizeof(char) );
2859 for (int i = 0 ; i < infoRec->rec.display.alpha_len ; i++) {
2860 string8[i] = infoRec->rec.display.alpha_buf[i];
2861 }
2862 string8[(int)infoRec->rec.display.alpha_len] = '\0';
2863 writeStringToParcel(p, (const char*)string8);
2864 free(string8);
2865 string8 = NULL;
2866 break;
2867 case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
2868 case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
2869 case RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
2870 if (infoRec->rec.number.len > CDMA_NUMBER_INFO_BUFFER_LENGTH) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002871 RLOGE("invalid display info response length %d \
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002872 expected not more than %d\n",
2873 (int)infoRec->rec.number.len,
2874 CDMA_NUMBER_INFO_BUFFER_LENGTH);
2875 return RIL_ERRNO_INVALID_RESPONSE;
2876 }
2877 string8 = (char*) malloc((infoRec->rec.number.len + 1)
2878 * sizeof(char) );
2879 for (int i = 0 ; i < infoRec->rec.number.len; i++) {
2880 string8[i] = infoRec->rec.number.buf[i];
2881 }
2882 string8[(int)infoRec->rec.number.len] = '\0';
2883 writeStringToParcel(p, (const char*)string8);
2884 free(string8);
2885 string8 = NULL;
2886 p.writeInt32(infoRec->rec.number.number_type);
2887 p.writeInt32(infoRec->rec.number.number_plan);
2888 p.writeInt32(infoRec->rec.number.pi);
2889 p.writeInt32(infoRec->rec.number.si);
2890 break;
2891 case RIL_CDMA_SIGNAL_INFO_REC:
2892 p.writeInt32(infoRec->rec.signal.isPresent);
2893 p.writeInt32(infoRec->rec.signal.signalType);
2894 p.writeInt32(infoRec->rec.signal.alertPitch);
2895 p.writeInt32(infoRec->rec.signal.signal);
2896
2897 appendPrintBuf("%sisPresent=%X, signalType=%X, \
2898 alertPitch=%X, signal=%X, ",
2899 printBuf, (int)infoRec->rec.signal.isPresent,
2900 (int)infoRec->rec.signal.signalType,
2901 (int)infoRec->rec.signal.alertPitch,
2902 (int)infoRec->rec.signal.signal);
2903 removeLastChar;
2904 break;
2905 case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
2906 if (infoRec->rec.redir.redirectingNumber.len >
2907 CDMA_NUMBER_INFO_BUFFER_LENGTH) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002908 RLOGE("invalid display info response length %d \
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002909 expected not more than %d\n",
2910 (int)infoRec->rec.redir.redirectingNumber.len,
2911 CDMA_NUMBER_INFO_BUFFER_LENGTH);
2912 return RIL_ERRNO_INVALID_RESPONSE;
2913 }
2914 string8 = (char*) malloc((infoRec->rec.redir.redirectingNumber
2915 .len + 1) * sizeof(char) );
2916 for (int i = 0;
2917 i < infoRec->rec.redir.redirectingNumber.len;
2918 i++) {
2919 string8[i] = infoRec->rec.redir.redirectingNumber.buf[i];
2920 }
2921 string8[(int)infoRec->rec.redir.redirectingNumber.len] = '\0';
2922 writeStringToParcel(p, (const char*)string8);
2923 free(string8);
2924 string8 = NULL;
2925 p.writeInt32(infoRec->rec.redir.redirectingNumber.number_type);
2926 p.writeInt32(infoRec->rec.redir.redirectingNumber.number_plan);
2927 p.writeInt32(infoRec->rec.redir.redirectingNumber.pi);
2928 p.writeInt32(infoRec->rec.redir.redirectingNumber.si);
2929 p.writeInt32(infoRec->rec.redir.redirectingReason);
2930 break;
2931 case RIL_CDMA_LINE_CONTROL_INFO_REC:
2932 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPolarityIncluded);
2933 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlToggle);
2934 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlReverse);
2935 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPowerDenial);
2936
2937 appendPrintBuf("%slineCtrlPolarityIncluded=%d, \
2938 lineCtrlToggle=%d, lineCtrlReverse=%d, \
2939 lineCtrlPowerDenial=%d, ", printBuf,
2940 (int)infoRec->rec.lineCtrl.lineCtrlPolarityIncluded,
2941 (int)infoRec->rec.lineCtrl.lineCtrlToggle,
2942 (int)infoRec->rec.lineCtrl.lineCtrlReverse,
2943 (int)infoRec->rec.lineCtrl.lineCtrlPowerDenial);
2944 removeLastChar;
2945 break;
2946 case RIL_CDMA_T53_CLIR_INFO_REC:
2947 p.writeInt32((int)(infoRec->rec.clir.cause));
2948
2949 appendPrintBuf("%scause%d", printBuf, infoRec->rec.clir.cause);
2950 removeLastChar;
2951 break;
2952 case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
2953 p.writeInt32(infoRec->rec.audioCtrl.upLink);
2954 p.writeInt32(infoRec->rec.audioCtrl.downLink);
2955
2956 appendPrintBuf("%supLink=%d, downLink=%d, ", printBuf,
2957 infoRec->rec.audioCtrl.upLink,
2958 infoRec->rec.audioCtrl.downLink);
2959 removeLastChar;
2960 break;
2961 case RIL_CDMA_T53_RELEASE_INFO_REC:
2962 // TODO(Moto): See David Krause, he has the answer:)
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002963 RLOGE("RIL_CDMA_T53_RELEASE_INFO_REC: return INVALID_RESPONSE");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002964 return RIL_ERRNO_INVALID_RESPONSE;
2965 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002966 RLOGE("Incorrect name value");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002967 return RIL_ERRNO_INVALID_RESPONSE;
2968 }
2969 }
2970 closeResponse;
2971
2972 return 0;
2973}
2974
2975static int responseRilSignalStrength(Parcel &p,
2976 void *response, size_t responselen) {
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05302977 int gsmSignalStrength;
2978 int cdmaDbm;
2979 int evdoDbm;
2980
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002981 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02002982 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002983 return RIL_ERRNO_INVALID_RESPONSE;
2984 }
2985
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002986 if (responselen >= sizeof (RIL_SignalStrength_v5)) {
Howard Sue32dbfd2015-01-07 15:55:57 +08002987 RIL_SignalStrength_v10 *p_cur = ((RIL_SignalStrength_v10 *) response);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02002988
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05302989 gsmSignalStrength = p_cur->GW_SignalStrength.signalStrength & 0xFF;
Utkarsh Gupta8ede9fa2015-04-23 13:21:49 +05302990
2991#ifdef MODEM_TYPE_XMM6260
2992 if (gsmSignalStrength < 0 ||
2993 (gsmSignalStrength > 31 && p_cur->GW_SignalStrength.signalStrength != 99)) {
2994 gsmSignalStrength = p_cur->CDMA_SignalStrength.dbm;
2995 }
2996#else
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05302997 if (gsmSignalStrength < 0) {
2998 gsmSignalStrength = 99;
2999 } else if (gsmSignalStrength > 31 && gsmSignalStrength != 99) {
3000 gsmSignalStrength = 31;
3001 }
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303002#endif
3003 p.writeInt32(gsmSignalStrength);
3004
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003005 p.writeInt32(p_cur->GW_SignalStrength.bitErrorRate);
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303006
Christopher N. Hesse7bf409e2015-06-26 14:53:56 +02003007#if defined(MODEM_TYPE_XMM6262) || defined(MODEM_TYPE_XMM7260) || defined(MODEM_TYPE_M7450)
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303008 cdmaDbm = p_cur->CDMA_SignalStrength.dbm & 0xFF;
3009 if (cdmaDbm < 0) {
3010 cdmaDbm = 99;
3011 } else if (cdmaDbm > 31 && cdmaDbm != 99) {
3012 cdmaDbm = 31;
3013 }
3014#else
Caio Schnepperec042542015-04-14 08:03:43 -03003015 cdmaDbm = p_cur->CDMA_SignalStrength.dbm;
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303016#endif
3017 p.writeInt32(cdmaDbm);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003018 p.writeInt32(p_cur->CDMA_SignalStrength.ecio);
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303019
Christopher N. Hesse7bf409e2015-06-26 14:53:56 +02003020#if defined(MODEM_TYPE_XMM6262) || defined(MODEM_TYPE_XMM7260) || defined(MODEM_TYPE_M7450)
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303021 evdoDbm = p_cur->EVDO_SignalStrength.dbm & 0xFF;
3022 if (evdoDbm < 0) {
3023 evdoDbm = 99;
3024 } else if (evdoDbm > 31 && evdoDbm != 99) {
3025 evdoDbm = 31;
3026 }
3027#else
3028 evdoDbm = p_cur->EVDO_SignalStrength.dbm;
3029#endif
3030 p.writeInt32(evdoDbm);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003031 p.writeInt32(p_cur->EVDO_SignalStrength.ecio);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003032 p.writeInt32(p_cur->EVDO_SignalStrength.signalNoiseRatio);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003033 if (responselen >= sizeof (RIL_SignalStrength_v6)) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003034 /*
Ethan Chend6e30652013-08-04 22:49:56 -07003035 * Fixup LTE for backwards compatibility
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003036 */
Ethan Chend6e30652013-08-04 22:49:56 -07003037 if (s_callbacks.version <= 6) {
3038 // signalStrength: -1 -> 99
3039 if (p_cur->LTE_SignalStrength.signalStrength == -1) {
3040 p_cur->LTE_SignalStrength.signalStrength = 99;
3041 }
3042 // rsrp: -1 -> INT_MAX all other negative value to positive.
3043 // So remap here
3044 if (p_cur->LTE_SignalStrength.rsrp == -1) {
3045 p_cur->LTE_SignalStrength.rsrp = INT_MAX;
3046 } else if (p_cur->LTE_SignalStrength.rsrp < -1) {
3047 p_cur->LTE_SignalStrength.rsrp = -p_cur->LTE_SignalStrength.rsrp;
3048 }
3049 // rsrq: -1 -> INT_MAX
3050 if (p_cur->LTE_SignalStrength.rsrq == -1) {
3051 p_cur->LTE_SignalStrength.rsrq = INT_MAX;
3052 }
3053 // Not remapping rssnr is already using INT_MAX
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003054
Ethan Chend6e30652013-08-04 22:49:56 -07003055 // cqi: -1 -> INT_MAX
3056 if (p_cur->LTE_SignalStrength.cqi == -1) {
3057 p_cur->LTE_SignalStrength.cqi = INT_MAX;
3058 }
3059 }
3060 p.writeInt32(p_cur->LTE_SignalStrength.signalStrength);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003061 p.writeInt32(p_cur->LTE_SignalStrength.rsrp);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003062 p.writeInt32(p_cur->LTE_SignalStrength.rsrq);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003063 p.writeInt32(p_cur->LTE_SignalStrength.rssnr);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003064 p.writeInt32(p_cur->LTE_SignalStrength.cqi);
Howard Sue32dbfd2015-01-07 15:55:57 +08003065 if (responselen >= sizeof (RIL_SignalStrength_v10)) {
3066 p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp);
3067 } else {
3068 p.writeInt32(INT_MAX);
3069 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003070 } else {
Ethan Chend6e30652013-08-04 22:49:56 -07003071 p.writeInt32(99);
3072 p.writeInt32(INT_MAX);
3073 p.writeInt32(INT_MAX);
3074 p.writeInt32(INT_MAX);
3075 p.writeInt32(INT_MAX);
Howard Sue32dbfd2015-01-07 15:55:57 +08003076 p.writeInt32(INT_MAX);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003077 }
3078
3079 startResponse;
3080 appendPrintBuf("%s[signalStrength=%d,bitErrorRate=%d,\
3081 CDMA_SS.dbm=%d,CDMA_SSecio=%d,\
3082 EVDO_SS.dbm=%d,EVDO_SS.ecio=%d,\
3083 EVDO_SS.signalNoiseRatio=%d,\
3084 LTE_SS.signalStrength=%d,LTE_SS.rsrp=%d,LTE_SS.rsrq=%d,\
Howard Sue32dbfd2015-01-07 15:55:57 +08003085 LTE_SS.rssnr=%d,LTE_SS.cqi=%d,TDSCDMA_SS.rscp=%d]",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003086 printBuf,
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303087 gsmSignalStrength,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003088 p_cur->GW_SignalStrength.bitErrorRate,
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303089 cdmaDbm,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003090 p_cur->CDMA_SignalStrength.ecio,
Utkarsh Gupta8a0d7402015-04-13 13:33:37 +05303091 evdoDbm,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003092 p_cur->EVDO_SignalStrength.ecio,
3093 p_cur->EVDO_SignalStrength.signalNoiseRatio,
3094 p_cur->LTE_SignalStrength.signalStrength,
3095 p_cur->LTE_SignalStrength.rsrp,
3096 p_cur->LTE_SignalStrength.rsrq,
3097 p_cur->LTE_SignalStrength.rssnr,
Howard Sue32dbfd2015-01-07 15:55:57 +08003098 p_cur->LTE_SignalStrength.cqi,
3099 p_cur->TD_SCDMA_SignalStrength.rscp);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003100 closeResponse;
3101
3102 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003103 RLOGE("invalid response length");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003104 return RIL_ERRNO_INVALID_RESPONSE;
3105 }
3106
3107 return 0;
3108}
3109
3110static int responseCallRing(Parcel &p, void *response, size_t responselen) {
3111 if ((response == NULL) || (responselen == 0)) {
3112 return responseVoid(p, response, responselen);
3113 } else {
3114 return responseCdmaSignalInfoRecord(p, response, responselen);
3115 }
3116}
3117
3118static int responseCdmaSignalInfoRecord(Parcel &p, void *response, size_t responselen) {
3119 if (response == NULL || responselen == 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003120 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003121 return RIL_ERRNO_INVALID_RESPONSE;
3122 }
3123
3124 if (responselen != sizeof (RIL_CDMA_SignalInfoRecord)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003125 RLOGE("invalid response length %d expected sizeof (RIL_CDMA_SignalInfoRecord) of %d\n",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003126 (int)responselen, (int)sizeof (RIL_CDMA_SignalInfoRecord));
3127 return RIL_ERRNO_INVALID_RESPONSE;
3128 }
3129
3130 startResponse;
3131
3132 RIL_CDMA_SignalInfoRecord *p_cur = ((RIL_CDMA_SignalInfoRecord *) response);
3133 marshallSignalInfoRecord(p, *p_cur);
3134
3135 appendPrintBuf("%s[isPresent=%d,signalType=%d,alertPitch=%d\
3136 signal=%d]",
3137 printBuf,
3138 p_cur->isPresent,
3139 p_cur->signalType,
3140 p_cur->alertPitch,
3141 p_cur->signal);
3142
3143 closeResponse;
3144 return 0;
3145}
3146
3147static int responseCdmaCallWaiting(Parcel &p, void *response,
3148 size_t responselen) {
3149 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003150 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003151 return RIL_ERRNO_INVALID_RESPONSE;
3152 }
3153
3154 if (responselen < sizeof(RIL_CDMA_CallWaiting_v6)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003155 RLOGW("Upgrade to ril version %d\n", RIL_VERSION);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003156 }
3157
3158 RIL_CDMA_CallWaiting_v6 *p_cur = ((RIL_CDMA_CallWaiting_v6 *) response);
3159
3160 writeStringToParcel(p, p_cur->number);
3161 p.writeInt32(p_cur->numberPresentation);
3162 writeStringToParcel(p, p_cur->name);
3163 marshallSignalInfoRecord(p, p_cur->signalInfoRecord);
3164
3165 if (responselen >= sizeof(RIL_CDMA_CallWaiting_v6)) {
3166 p.writeInt32(p_cur->number_type);
3167 p.writeInt32(p_cur->number_plan);
3168 } else {
3169 p.writeInt32(0);
3170 p.writeInt32(0);
3171 }
3172
3173 startResponse;
3174 appendPrintBuf("%snumber=%s,numberPresentation=%d, name=%s,\
3175 signalInfoRecord[isPresent=%d,signalType=%d,alertPitch=%d\
3176 signal=%d,number_type=%d,number_plan=%d]",
3177 printBuf,
3178 p_cur->number,
3179 p_cur->numberPresentation,
3180 p_cur->name,
3181 p_cur->signalInfoRecord.isPresent,
3182 p_cur->signalInfoRecord.signalType,
3183 p_cur->signalInfoRecord.alertPitch,
3184 p_cur->signalInfoRecord.signal,
3185 p_cur->number_type,
3186 p_cur->number_plan);
3187 closeResponse;
3188
3189 return 0;
3190}
3191
3192static int responseSimRefresh(Parcel &p, void *response, size_t responselen) {
3193 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003194 RLOGE("responseSimRefresh: invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003195 return RIL_ERRNO_INVALID_RESPONSE;
3196 }
3197
3198 startResponse;
3199 if (s_callbacks.version == 7) {
3200 RIL_SimRefreshResponse_v7 *p_cur = ((RIL_SimRefreshResponse_v7 *) response);
3201 p.writeInt32(p_cur->result);
3202 p.writeInt32(p_cur->ef_id);
3203 writeStringToParcel(p, p_cur->aid);
3204
3205 appendPrintBuf("%sresult=%d, ef_id=%d, aid=%s",
3206 printBuf,
3207 p_cur->result,
3208 p_cur->ef_id,
3209 p_cur->aid);
3210 } else {
3211 int *p_cur = ((int *) response);
3212 p.writeInt32(p_cur[0]);
3213 p.writeInt32(p_cur[1]);
3214 writeStringToParcel(p, NULL);
3215
3216 appendPrintBuf("%sresult=%d, ef_id=%d",
3217 printBuf,
3218 p_cur[0],
3219 p_cur[1]);
3220 }
3221 closeResponse;
3222
3223 return 0;
3224}
3225
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003226static int responseCellInfoList(Parcel &p, void *response, size_t responselen)
3227{
3228 if (response == NULL && responselen != 0) {
3229 RLOGE("invalid response: NULL");
3230 return RIL_ERRNO_INVALID_RESPONSE;
3231 }
3232
3233 if (responselen % sizeof(RIL_CellInfo) != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08003234 RLOGE("responseCellInfoList: invalid response length %d expected multiple of %d",
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003235 (int)responselen, (int)sizeof(RIL_CellInfo));
3236 return RIL_ERRNO_INVALID_RESPONSE;
3237 }
3238
3239 int num = responselen / sizeof(RIL_CellInfo);
3240 p.writeInt32(num);
3241
3242 RIL_CellInfo *p_cur = (RIL_CellInfo *) response;
3243 startResponse;
3244 int i;
3245 for (i = 0; i < num; i++) {
3246 appendPrintBuf("%s[%d: type=%d,registered=%d,timeStampType=%d,timeStamp=%lld", printBuf, i,
3247 p_cur->cellInfoType, p_cur->registered, p_cur->timeStampType, p_cur->timeStamp);
3248 p.writeInt32((int)p_cur->cellInfoType);
3249 p.writeInt32(p_cur->registered);
3250 p.writeInt32(p_cur->timeStampType);
3251 p.writeInt64(p_cur->timeStamp);
3252 switch(p_cur->cellInfoType) {
3253 case RIL_CELL_INFO_TYPE_GSM: {
3254 appendPrintBuf("%s GSM id: mcc=%d,mnc=%d,lac=%d,cid=%d,", printBuf,
3255 p_cur->CellInfo.gsm.cellIdentityGsm.mcc,
3256 p_cur->CellInfo.gsm.cellIdentityGsm.mnc,
3257 p_cur->CellInfo.gsm.cellIdentityGsm.lac,
3258 p_cur->CellInfo.gsm.cellIdentityGsm.cid);
3259 appendPrintBuf("%s gsmSS: ss=%d,ber=%d],", printBuf,
3260 p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength,
3261 p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
3262
3263 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mcc);
3264 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mnc);
3265 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.lac);
3266 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.cid);
3267 p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength);
3268 p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
3269 break;
3270 }
3271 case RIL_CELL_INFO_TYPE_WCDMA: {
3272 appendPrintBuf("%s WCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,psc=%d,", printBuf,
3273 p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc,
3274 p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc,
3275 p_cur->CellInfo.wcdma.cellIdentityWcdma.lac,
3276 p_cur->CellInfo.wcdma.cellIdentityWcdma.cid,
3277 p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
3278 appendPrintBuf("%s wcdmaSS: ss=%d,ber=%d],", printBuf,
3279 p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength,
3280 p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
3281
3282 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc);
3283 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc);
3284 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.lac);
3285 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.cid);
3286 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
3287 p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength);
3288 p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
3289 break;
3290 }
3291 case RIL_CELL_INFO_TYPE_CDMA: {
3292 appendPrintBuf("%s CDMA id: nId=%d,sId=%d,bsId=%d,long=%d,lat=%d", printBuf,
3293 p_cur->CellInfo.cdma.cellIdentityCdma.networkId,
3294 p_cur->CellInfo.cdma.cellIdentityCdma.systemId,
3295 p_cur->CellInfo.cdma.cellIdentityCdma.basestationId,
3296 p_cur->CellInfo.cdma.cellIdentityCdma.longitude,
3297 p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
3298
3299 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.networkId);
3300 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.systemId);
3301 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.basestationId);
3302 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.longitude);
3303 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
3304
3305 appendPrintBuf("%s cdmaSS: dbm=%d ecio=%d evdoSS: dbm=%d,ecio=%d,snr=%d", printBuf,
3306 p_cur->CellInfo.cdma.signalStrengthCdma.dbm,
3307 p_cur->CellInfo.cdma.signalStrengthCdma.ecio,
3308 p_cur->CellInfo.cdma.signalStrengthEvdo.dbm,
3309 p_cur->CellInfo.cdma.signalStrengthEvdo.ecio,
3310 p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
3311
3312 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.dbm);
3313 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.ecio);
3314 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.dbm);
3315 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.ecio);
3316 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
3317 break;
3318 }
3319 case RIL_CELL_INFO_TYPE_LTE: {
3320 appendPrintBuf("%s LTE id: mcc=%d,mnc=%d,ci=%d,pci=%d,tac=%d", printBuf,
3321 p_cur->CellInfo.lte.cellIdentityLte.mcc,
3322 p_cur->CellInfo.lte.cellIdentityLte.mnc,
3323 p_cur->CellInfo.lte.cellIdentityLte.ci,
3324 p_cur->CellInfo.lte.cellIdentityLte.pci,
3325 p_cur->CellInfo.lte.cellIdentityLte.tac);
3326
3327 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mcc);
3328 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mnc);
3329 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.ci);
3330 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.pci);
3331 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.tac);
3332
3333 appendPrintBuf("%s lteSS: ss=%d,rsrp=%d,rsrq=%d,rssnr=%d,cqi=%d,ta=%d", printBuf,
3334 p_cur->CellInfo.lte.signalStrengthLte.signalStrength,
3335 p_cur->CellInfo.lte.signalStrengthLte.rsrp,
3336 p_cur->CellInfo.lte.signalStrengthLte.rsrq,
3337 p_cur->CellInfo.lte.signalStrengthLte.rssnr,
3338 p_cur->CellInfo.lte.signalStrengthLte.cqi,
3339 p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
3340 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.signalStrength);
3341 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrp);
3342 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrq);
3343 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rssnr);
3344 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.cqi);
3345 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
3346 break;
3347 }
Howard Sue32dbfd2015-01-07 15:55:57 +08003348 case RIL_CELL_INFO_TYPE_TD_SCDMA: {
3349 appendPrintBuf("%s TDSCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,cpid=%d,", printBuf,
3350 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc,
3351 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc,
3352 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac,
3353 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid,
3354 p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid);
3355 appendPrintBuf("%s tdscdmaSS: rscp=%d],", printBuf,
3356 p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp);
3357
3358 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc);
3359 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc);
3360 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac);
3361 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid);
3362 p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid);
3363 p.writeInt32(p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp);
3364 break;
3365 }
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003366 }
3367 p_cur += 1;
3368 }
3369 removeLastChar;
3370 closeResponse;
3371
3372 return 0;
3373}
3374
Howard Sue32dbfd2015-01-07 15:55:57 +08003375static int responseHardwareConfig(Parcel &p, void *response, size_t responselen)
3376{
3377 if (response == NULL && responselen != 0) {
3378 RLOGE("invalid response: NULL");
3379 return RIL_ERRNO_INVALID_RESPONSE;
3380 }
3381
3382 if (responselen % sizeof(RIL_HardwareConfig) != 0) {
3383 RLOGE("responseHardwareConfig: invalid response length %d expected multiple of %d",
3384 (int)responselen, (int)sizeof(RIL_HardwareConfig));
3385 return RIL_ERRNO_INVALID_RESPONSE;
3386 }
3387
3388 int num = responselen / sizeof(RIL_HardwareConfig);
3389 int i;
3390 RIL_HardwareConfig *p_cur = (RIL_HardwareConfig *) response;
3391
3392 p.writeInt32(num);
3393
3394 startResponse;
3395 for (i = 0; i < num; i++) {
3396 switch (p_cur[i].type) {
3397 case RIL_HARDWARE_CONFIG_MODEM: {
3398 writeStringToParcel(p, p_cur[i].uuid);
3399 p.writeInt32((int)p_cur[i].state);
3400 p.writeInt32(p_cur[i].cfg.modem.rat);
3401 p.writeInt32(p_cur[i].cfg.modem.maxVoice);
3402 p.writeInt32(p_cur[i].cfg.modem.maxData);
3403 p.writeInt32(p_cur[i].cfg.modem.maxStandby);
3404
3405 appendPrintBuf("%s modem: uuid=%s,state=%d,rat=%08x,maxV=%d,maxD=%d,maxS=%d", printBuf,
3406 p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.modem.rat,
3407 p_cur[i].cfg.modem.maxVoice, p_cur[i].cfg.modem.maxData, p_cur[i].cfg.modem.maxStandby);
3408 break;
3409 }
3410 case RIL_HARDWARE_CONFIG_SIM: {
3411 writeStringToParcel(p, p_cur[i].uuid);
3412 p.writeInt32((int)p_cur[i].state);
3413 writeStringToParcel(p, p_cur[i].cfg.sim.modemUuid);
3414
3415 appendPrintBuf("%s sim: uuid=%s,state=%d,modem-uuid=%s", printBuf,
3416 p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.sim.modemUuid);
3417 break;
3418 }
3419 }
3420 }
3421 removeLastChar;
3422 closeResponse;
3423 return 0;
3424}
3425
Howard Subd82ef12015-04-12 10:25:05 +02003426static int responseRadioCapability(Parcel &p, void *response, size_t responselen) {
3427 if (response == NULL) {
3428 RLOGE("invalid response: NULL");
3429 return RIL_ERRNO_INVALID_RESPONSE;
3430 }
3431
3432 if (responselen != sizeof (RIL_RadioCapability) ) {
3433 RLOGE("invalid response length was %d expected %d",
3434 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
3435 return RIL_ERRNO_INVALID_RESPONSE;
3436 }
3437
3438 RIL_RadioCapability *p_cur = (RIL_RadioCapability *) response;
3439 p.writeInt32(p_cur->version);
3440 p.writeInt32(p_cur->session);
3441 p.writeInt32(p_cur->phase);
3442 p.writeInt32(p_cur->rat);
3443 writeStringToParcel(p, p_cur->logicalModemUuid);
3444 p.writeInt32(p_cur->status);
3445
3446 startResponse;
3447 appendPrintBuf("%s[version=%d,session=%d,phase=%d,\
Andreas Schneidera8d09502015-06-23 18:41:38 +02003448 rat=%d,logicalModemUuid=%s,status=%d]",
Howard Subd82ef12015-04-12 10:25:05 +02003449 printBuf,
3450 p_cur->version,
3451 p_cur->session,
3452 p_cur->phase,
3453 p_cur->rat,
3454 p_cur->logicalModemUuid,
3455 p_cur->status);
3456 closeResponse;
3457 return 0;
3458}
3459
3460static int responseSSData(Parcel &p, void *response, size_t responselen) {
3461 RLOGD("In responseSSData");
3462 int num;
3463
3464 if (response == NULL && responselen != 0) {
3465 RLOGE("invalid response length was %d expected %d",
3466 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
3467 return RIL_ERRNO_INVALID_RESPONSE;
3468 }
3469
3470 if (responselen != sizeof(RIL_StkCcUnsolSsResponse)) {
3471 RLOGE("invalid response length %d, expected %d",
3472 (int)responselen, (int)sizeof(RIL_StkCcUnsolSsResponse));
3473 return RIL_ERRNO_INVALID_RESPONSE;
3474 }
3475
3476 startResponse;
3477 RIL_StkCcUnsolSsResponse *p_cur = (RIL_StkCcUnsolSsResponse *) response;
3478 p.writeInt32(p_cur->serviceType);
3479 p.writeInt32(p_cur->requestType);
3480 p.writeInt32(p_cur->teleserviceType);
3481 p.writeInt32(p_cur->serviceClass);
3482 p.writeInt32(p_cur->result);
3483
3484 if (isServiceTypeCfQuery(p_cur->serviceType, p_cur->requestType)) {
3485 RLOGD("responseSSData CF type, num of Cf elements %d", p_cur->cfData.numValidIndexes);
3486 if (p_cur->cfData.numValidIndexes > NUM_SERVICE_CLASSES) {
3487 RLOGE("numValidIndexes is greater than max value %d, "
3488 "truncating it to max value", NUM_SERVICE_CLASSES);
3489 p_cur->cfData.numValidIndexes = NUM_SERVICE_CLASSES;
3490 }
3491 /* number of call info's */
3492 p.writeInt32(p_cur->cfData.numValidIndexes);
3493
3494 for (int i = 0; i < p_cur->cfData.numValidIndexes; i++) {
3495 RIL_CallForwardInfo cf = p_cur->cfData.cfInfo[i];
3496
3497 p.writeInt32(cf.status);
3498 p.writeInt32(cf.reason);
3499 p.writeInt32(cf.serviceClass);
3500 p.writeInt32(cf.toa);
3501 writeStringToParcel(p, cf.number);
3502 p.writeInt32(cf.timeSeconds);
3503 appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
3504 (cf.status==1)?"enable":"disable", cf.reason, cf.serviceClass, cf.toa,
3505 (char*)cf.number, cf.timeSeconds);
3506 RLOGD("Data: %d,reason=%d,cls=%d,toa=%d,num=%s,tout=%d],", cf.status,
3507 cf.reason, cf.serviceClass, cf.toa, (char*)cf.number, cf.timeSeconds);
3508 }
3509 } else {
3510 p.writeInt32 (SS_INFO_MAX);
3511
3512 /* each int*/
3513 for (int i = 0; i < SS_INFO_MAX; i++) {
3514 appendPrintBuf("%s%d,", printBuf, p_cur->ssInfo[i]);
3515 RLOGD("Data: %d",p_cur->ssInfo[i]);
3516 p.writeInt32(p_cur->ssInfo[i]);
3517 }
3518 }
3519 removeLastChar;
3520 closeResponse;
3521
3522 return 0;
3523}
3524
3525static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType) {
3526 if ((reqType == SS_INTERROGATION) &&
3527 (serType == SS_CFU ||
3528 serType == SS_CF_BUSY ||
3529 serType == SS_CF_NO_REPLY ||
3530 serType == SS_CF_NOT_REACHABLE ||
3531 serType == SS_CF_ALL ||
3532 serType == SS_CF_ALL_CONDITIONAL)) {
3533 return true;
3534 }
3535 return false;
3536}
3537
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003538static void triggerEvLoop() {
3539 int ret;
3540 if (!pthread_equal(pthread_self(), s_tid_dispatch)) {
3541 /* trigger event loop to wakeup. No reason to do this,
3542 * if we're in the event loop thread */
3543 do {
3544 ret = write (s_fdWakeupWrite, " ", 1);
3545 } while (ret < 0 && errno == EINTR);
3546 }
3547}
3548
3549static void rilEventAddWakeup(struct ril_event *ev) {
3550 ril_event_add(ev);
3551 triggerEvLoop();
3552}
3553
3554static void sendSimStatusAppInfo(Parcel &p, int num_apps, RIL_AppStatus appStatus[]) {
3555 p.writeInt32(num_apps);
3556 startResponse;
3557 for (int i = 0; i < num_apps; i++) {
3558 p.writeInt32(appStatus[i].app_type);
3559 p.writeInt32(appStatus[i].app_state);
3560 p.writeInt32(appStatus[i].perso_substate);
3561 writeStringToParcel(p, (const char*)(appStatus[i].aid_ptr));
3562 writeStringToParcel(p, (const char*)
3563 (appStatus[i].app_label_ptr));
3564 p.writeInt32(appStatus[i].pin1_replaced);
3565 p.writeInt32(appStatus[i].pin1);
3566 p.writeInt32(appStatus[i].pin2);
3567 appendPrintBuf("%s[app_type=%d,app_state=%d,perso_substate=%d,\
3568 aid_ptr=%s,app_label_ptr=%s,pin1_replaced=%d,pin1=%d,pin2=%d],",
3569 printBuf,
3570 appStatus[i].app_type,
3571 appStatus[i].app_state,
3572 appStatus[i].perso_substate,
3573 appStatus[i].aid_ptr,
3574 appStatus[i].app_label_ptr,
3575 appStatus[i].pin1_replaced,
3576 appStatus[i].pin1,
3577 appStatus[i].pin2);
3578 }
3579 closeResponse;
3580}
3581
3582static int responseSimStatus(Parcel &p, void *response, size_t responselen) {
Howard Sue32dbfd2015-01-07 15:55:57 +08003583 int i;
3584
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003585 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003586 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003587 return RIL_ERRNO_INVALID_RESPONSE;
3588 }
3589
3590 if (responselen == sizeof (RIL_CardStatus_v6)) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003591 RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
3592
3593 p.writeInt32(p_cur->card_state);
3594 p.writeInt32(p_cur->universal_pin_state);
3595 p.writeInt32(p_cur->gsm_umts_subscription_app_index);
3596 p.writeInt32(p_cur->cdma_subscription_app_index);
3597 p.writeInt32(p_cur->ims_subscription_app_index);
3598
3599 sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
3600 } else if (responselen == sizeof (RIL_CardStatus_v5)) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003601 RIL_CardStatus_v5 *p_cur = ((RIL_CardStatus_v5 *) response);
3602
3603 p.writeInt32(p_cur->card_state);
3604 p.writeInt32(p_cur->universal_pin_state);
3605 p.writeInt32(p_cur->gsm_umts_subscription_app_index);
3606 p.writeInt32(p_cur->cdma_subscription_app_index);
3607 p.writeInt32(-1);
3608
3609 sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
3610 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003611 RLOGE("responseSimStatus: A RilCardStatus_v6 or _v5 expected\n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003612 return RIL_ERRNO_INVALID_RESPONSE;
3613 }
3614
3615 return 0;
3616}
3617
3618static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen) {
3619 int num = responselen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *);
3620 p.writeInt32(num);
3621
3622 startResponse;
3623 RIL_GSM_BroadcastSmsConfigInfo **p_cur =
3624 (RIL_GSM_BroadcastSmsConfigInfo **) response;
3625 for (int i = 0; i < num; i++) {
3626 p.writeInt32(p_cur[i]->fromServiceId);
3627 p.writeInt32(p_cur[i]->toServiceId);
3628 p.writeInt32(p_cur[i]->fromCodeScheme);
3629 p.writeInt32(p_cur[i]->toCodeScheme);
3630 p.writeInt32(p_cur[i]->selected);
3631
3632 appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId=%d, \
3633 fromCodeScheme=%d, toCodeScheme=%d, selected =%d]",
3634 printBuf, i, p_cur[i]->fromServiceId, p_cur[i]->toServiceId,
3635 p_cur[i]->fromCodeScheme, p_cur[i]->toCodeScheme,
3636 p_cur[i]->selected);
3637 }
3638 closeResponse;
3639
3640 return 0;
3641}
3642
3643static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen) {
3644 RIL_CDMA_BroadcastSmsConfigInfo **p_cur =
3645 (RIL_CDMA_BroadcastSmsConfigInfo **) response;
3646
3647 int num = responselen / sizeof (RIL_CDMA_BroadcastSmsConfigInfo *);
3648 p.writeInt32(num);
3649
3650 startResponse;
3651 for (int i = 0 ; i < num ; i++ ) {
3652 p.writeInt32(p_cur[i]->service_category);
3653 p.writeInt32(p_cur[i]->language);
3654 p.writeInt32(p_cur[i]->selected);
3655
3656 appendPrintBuf("%s [%d: srvice_category=%d, language =%d, \
3657 selected =%d], ",
3658 printBuf, i, p_cur[i]->service_category, p_cur[i]->language,
3659 p_cur[i]->selected);
3660 }
3661 closeResponse;
3662
3663 return 0;
3664}
3665
3666static int responseCdmaSms(Parcel &p, void *response, size_t responselen) {
3667 int num;
3668 int digitCount;
3669 int digitLimit;
3670 uint8_t uct;
3671 void* dest;
3672
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003673 RLOGD("Inside responseCdmaSms");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003674
3675 if (response == NULL && responselen != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003676 RLOGE("invalid response: NULL");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003677 return RIL_ERRNO_INVALID_RESPONSE;
3678 }
3679
3680 if (responselen != sizeof(RIL_CDMA_SMS_Message)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003681 RLOGE("invalid response length was %d expected %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003682 (int)responselen, (int)sizeof(RIL_CDMA_SMS_Message));
3683 return RIL_ERRNO_INVALID_RESPONSE;
3684 }
3685
3686 RIL_CDMA_SMS_Message *p_cur = (RIL_CDMA_SMS_Message *) response;
3687 p.writeInt32(p_cur->uTeleserviceID);
3688 p.write(&(p_cur->bIsServicePresent),sizeof(uct));
3689 p.writeInt32(p_cur->uServicecategory);
3690 p.writeInt32(p_cur->sAddress.digit_mode);
3691 p.writeInt32(p_cur->sAddress.number_mode);
3692 p.writeInt32(p_cur->sAddress.number_type);
3693 p.writeInt32(p_cur->sAddress.number_plan);
3694 p.write(&(p_cur->sAddress.number_of_digits), sizeof(uct));
3695 digitLimit= MIN((p_cur->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
3696 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
3697 p.write(&(p_cur->sAddress.digits[digitCount]),sizeof(uct));
3698 }
3699
3700 p.writeInt32(p_cur->sSubAddress.subaddressType);
3701 p.write(&(p_cur->sSubAddress.odd),sizeof(uct));
3702 p.write(&(p_cur->sSubAddress.number_of_digits),sizeof(uct));
3703 digitLimit= MIN((p_cur->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
3704 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
3705 p.write(&(p_cur->sSubAddress.digits[digitCount]),sizeof(uct));
3706 }
3707
3708 digitLimit= MIN((p_cur->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
3709 p.writeInt32(p_cur->uBearerDataLen);
3710 for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
3711 p.write(&(p_cur->aBearerData[digitCount]), sizeof(uct));
3712 }
3713
3714 startResponse;
3715 appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
3716 sAddress.digit_mode=%d, sAddress.number_mode=%d, sAddress.number_type=%d, ",
3717 printBuf, p_cur->uTeleserviceID,p_cur->bIsServicePresent,p_cur->uServicecategory,
3718 p_cur->sAddress.digit_mode, p_cur->sAddress.number_mode,p_cur->sAddress.number_type);
3719 closeResponse;
3720
3721 return 0;
3722}
3723
Howard Sue32dbfd2015-01-07 15:55:57 +08003724static int responseDcRtInfo(Parcel &p, void *response, size_t responselen)
3725{
3726 int num = responselen / sizeof(RIL_DcRtInfo);
3727 if ((responselen % sizeof(RIL_DcRtInfo) != 0) || (num != 1)) {
3728 RLOGE("responseDcRtInfo: invalid response length %d expected multiple of %d",
3729 (int)responselen, (int)sizeof(RIL_DcRtInfo));
3730 return RIL_ERRNO_INVALID_RESPONSE;
3731 }
3732
3733 startResponse;
3734 RIL_DcRtInfo *pDcRtInfo = (RIL_DcRtInfo *)response;
3735 p.writeInt64(pDcRtInfo->time);
3736 p.writeInt32(pDcRtInfo->powerState);
3737 appendPrintBuf("%s[time=%d,powerState=%d]", printBuf,
3738 pDcRtInfo->time,
Andreas Schneidera8d09502015-06-23 18:41:38 +02003739 (int)pDcRtInfo->powerState);
Howard Sue32dbfd2015-01-07 15:55:57 +08003740 closeResponse;
3741
3742 return 0;
3743}
3744
fenglu9bdede02015-04-14 14:53:55 -07003745static int responseLceStatus(Parcel &p, void *response, size_t responselen) {
3746 if (response == NULL || responselen != sizeof(RIL_LceStatusInfo)) {
3747 if (response == NULL) {
3748 RLOGE("invalid response: NULL");
3749 }
3750 else {
3751 RLOGE("responseLceStatus: invalid response length %d expecting len: d%",
3752 sizeof(RIL_LceStatusInfo), responselen);
3753 }
3754 return RIL_ERRNO_INVALID_RESPONSE;
3755 }
3756
3757 RIL_LceStatusInfo *p_cur = (RIL_LceStatusInfo *)response;
3758 p.write((void *)p_cur, 1); // p_cur->lce_status takes one byte.
3759 p.writeInt32(p_cur->actual_interval_ms);
3760
3761 startResponse;
3762 appendPrintBuf("LCE Status: %d, actual_interval_ms: %d",
3763 p_cur->lce_status, p_cur->actual_interval_ms);
3764 closeResponse;
3765
3766 return 0;
3767}
3768
3769static int responseLceData(Parcel &p, void *response, size_t responselen) {
3770 if (response == NULL || responselen != sizeof(RIL_LceDataInfo)) {
3771 if (response == NULL) {
3772 RLOGE("invalid response: NULL");
3773 }
3774 else {
3775 RLOGE("responseLceData: invalid response length %d expecting len: d%",
3776 sizeof(RIL_LceDataInfo), responselen);
3777 }
3778 return RIL_ERRNO_INVALID_RESPONSE;
3779 }
3780
3781 RIL_LceDataInfo *p_cur = (RIL_LceDataInfo *)response;
3782 p.writeInt32(p_cur->last_hop_capacity_kbps);
3783
3784 /* p_cur->confidence_level and p_cur->lce_suspended take 1 byte each.*/
3785 p.write((void *)&(p_cur->confidence_level), 1);
3786 p.write((void *)&(p_cur->lce_suspended), 1);
3787
3788 startResponse;
3789 appendPrintBuf("LCE info received: capacity %d confidence level %d
3790 and suspended %d",
3791 p_cur->last_hop_capacity_kbps, p_cur->confidence_level,
3792 p_cur->lce_suspended);
3793 closeResponse;
3794
3795 return 0;
3796}
3797
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003798/**
3799 * A write on the wakeup fd is done just to pop us out of select()
3800 * We empty the buffer here and then ril_event will reset the timers on the
3801 * way back down
3802 */
3803static void processWakeupCallback(int fd, short flags, void *param) {
3804 char buff[16];
3805 int ret;
3806
Ethan Chend6e30652013-08-04 22:49:56 -07003807 RLOGV("processWakeupCallback");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003808
3809 /* empty our wakeup socket out */
3810 do {
3811 ret = read(s_fdWakeupRead, &buff, sizeof(buff));
3812 } while (ret > 0 || (ret < 0 && errno == EINTR));
3813}
3814
Howard Sue32dbfd2015-01-07 15:55:57 +08003815static void onCommandsSocketClosed(RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003816 int ret;
3817 RequestInfo *p_cur;
Howard Sue32dbfd2015-01-07 15:55:57 +08003818 /* Hook for current context
3819 pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
3820 pthread_mutex_t * pendingRequestsMutexHook = &s_pendingRequestsMutex;
3821 /* pendingRequestsHook refer to &s_pendingRequests */
3822 RequestInfo ** pendingRequestsHook = &s_pendingRequests;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003823
Howard Sue32dbfd2015-01-07 15:55:57 +08003824#if (SIM_COUNT >= 2)
3825 if (socket_id == RIL_SOCKET_2) {
3826 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
3827 pendingRequestsHook = &s_pendingRequests_socket2;
3828 }
3829#if (SIM_COUNT >= 3)
3830 else if (socket_id == RIL_SOCKET_3) {
3831 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
3832 pendingRequestsHook = &s_pendingRequests_socket3;
3833 }
3834#endif
3835#if (SIM_COUNT >= 4)
3836 else if (socket_id == RIL_SOCKET_4) {
3837 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
3838 pendingRequestsHook = &s_pendingRequests_socket4;
3839 }
3840#endif
3841#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003842 /* mark pending requests as "cancelled" so we dont report responses */
Howard Sue32dbfd2015-01-07 15:55:57 +08003843 ret = pthread_mutex_lock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003844 assert (ret == 0);
3845
Howard Sue32dbfd2015-01-07 15:55:57 +08003846 p_cur = *pendingRequestsHook;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003847
Howard Sue32dbfd2015-01-07 15:55:57 +08003848 for (p_cur = *pendingRequestsHook
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003849 ; p_cur != NULL
3850 ; p_cur = p_cur->p_next
3851 ) {
3852 p_cur->cancelled = 1;
3853 }
3854
Howard Sue32dbfd2015-01-07 15:55:57 +08003855 ret = pthread_mutex_unlock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003856 assert (ret == 0);
3857}
3858
3859static void processCommandsCallback(int fd, short flags, void *param) {
3860 RecordStream *p_rs;
3861 void *p_record;
3862 size_t recordlen;
3863 int ret;
Howard Sue32dbfd2015-01-07 15:55:57 +08003864 SocketListenParam *p_info = (SocketListenParam *)param;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003865
Howard Sue32dbfd2015-01-07 15:55:57 +08003866 assert(fd == p_info->fdCommand);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003867
Howard Sue32dbfd2015-01-07 15:55:57 +08003868 p_rs = p_info->p_rs;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003869
3870 for (;;) {
3871 /* loop until EAGAIN/EINTR, end of stream, or other error */
3872 ret = record_stream_get_next(p_rs, &p_record, &recordlen);
3873
3874 if (ret == 0 && p_record == NULL) {
3875 /* end-of-stream */
3876 break;
3877 } else if (ret < 0) {
3878 break;
3879 } else if (ret == 0) { /* && p_record != NULL */
Howard Sue32dbfd2015-01-07 15:55:57 +08003880 processCommandBuffer(p_record, recordlen, p_info->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003881 }
3882 }
3883
3884 if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) {
3885 /* fatal error or end-of-stream */
3886 if (ret != 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003887 RLOGE("error on reading command socket errno:%d\n", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003888 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003889 RLOGW("EOS. Closing command socket.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003890 }
3891
Howard Sue32dbfd2015-01-07 15:55:57 +08003892 close(fd);
3893 p_info->fdCommand = -1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003894
Howard Sue32dbfd2015-01-07 15:55:57 +08003895 ril_event_del(p_info->commands_event);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003896
3897 record_stream_free(p_rs);
3898
3899 /* start listening for new connections again */
3900 rilEventAddWakeup(&s_listen_event);
3901
Howard Sue32dbfd2015-01-07 15:55:57 +08003902 onCommandsSocketClosed(p_info->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003903 }
3904}
3905
Howard Subd82ef12015-04-12 10:25:05 +02003906
Howard Sue32dbfd2015-01-07 15:55:57 +08003907static void onNewCommandConnect(RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003908 // Inform we are connected and the ril version
3909 int rilVer = s_callbacks.version;
Howard Sue32dbfd2015-01-07 15:55:57 +08003910 RIL_UNSOL_RESPONSE(RIL_UNSOL_RIL_CONNECTED,
3911 &rilVer, sizeof(rilVer), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003912
3913 // implicit radio state changed
Howard Sue32dbfd2015-01-07 15:55:57 +08003914 RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
3915 NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003916
3917 // Send last NITZ time data, in case it was missed
3918 if (s_lastNITZTimeData != NULL) {
Howard Sue32dbfd2015-01-07 15:55:57 +08003919 sendResponseRaw(s_lastNITZTimeData, s_lastNITZTimeDataSize, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003920
3921 free(s_lastNITZTimeData);
3922 s_lastNITZTimeData = NULL;
3923 }
3924
3925 // Get version string
3926 if (s_callbacks.getVersion != NULL) {
3927 const char *version;
3928 version = s_callbacks.getVersion();
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003929 RLOGI("RIL Daemon version: %s\n", version);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003930
3931 property_set(PROPERTY_RIL_IMPL, version);
3932 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003933 RLOGI("RIL Daemon version: unavailable\n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003934 property_set(PROPERTY_RIL_IMPL, "unavailable");
3935 }
3936
3937}
3938
3939static void listenCallback (int fd, short flags, void *param) {
3940 int ret;
3941 int err;
3942 int is_phone_socket;
Howard Sue32dbfd2015-01-07 15:55:57 +08003943 int fdCommand = -1;
Dheeraj Shettycc231012014-07-02 21:27:57 +02003944 char* processName;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003945 RecordStream *p_rs;
Dheeraj Shettycc231012014-07-02 21:27:57 +02003946 MySocketListenParam* listenParam;
3947 RilSocket *sapSocket = NULL;
3948 socketClient *sClient = NULL;
3949
Howard Sue32dbfd2015-01-07 15:55:57 +08003950 SocketListenParam *p_info = (SocketListenParam *)param;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003951
Dheeraj Shettycc231012014-07-02 21:27:57 +02003952 if(RIL_SAP_SOCKET == p_info->type) {
3953 listenParam = (MySocketListenParam *)param;
3954 sapSocket = listenParam->socket;
3955 }
3956
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003957 struct sockaddr_un peeraddr;
3958 socklen_t socklen = sizeof (peeraddr);
3959
3960 struct ucred creds;
3961 socklen_t szCreds = sizeof(creds);
3962
3963 struct passwd *pwd = NULL;
3964
Dheeraj Shettycc231012014-07-02 21:27:57 +02003965 if(NULL == sapSocket) {
3966 assert (*p_info->fdCommand < 0);
3967 assert (fd == *p_info->fdListen);
3968 processName = PHONE_PROCESS;
3969 } else {
3970 assert (sapSocket->commandFd < 0);
3971 assert (fd == sapSocket->listenFd);
3972 processName = BLUETOOTH_PROCESS;
3973 }
3974
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003975
Howard Sue32dbfd2015-01-07 15:55:57 +08003976 fdCommand = accept(fd, (sockaddr *) &peeraddr, &socklen);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003977
Howard Sue32dbfd2015-01-07 15:55:57 +08003978 if (fdCommand < 0 ) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02003979 RLOGE("Error on accept() errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003980 /* start listening for new connections again */
Dheeraj Shettycc231012014-07-02 21:27:57 +02003981 if(NULL == sapSocket) {
3982 rilEventAddWakeup(p_info->listen_event);
3983 } else {
3984 rilEventAddWakeup(sapSocket->getListenEvent());
3985 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003986 return;
3987 }
3988
3989 /* check the credential of the other side and only accept socket from
3990 * phone process
3991 */
3992 errno = 0;
3993 is_phone_socket = 0;
3994
Howard Sue32dbfd2015-01-07 15:55:57 +08003995 err = getsockopt(fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02003996
3997 if (err == 0 && szCreds > 0) {
3998 errno = 0;
3999 pwd = getpwuid(creds.uid);
4000 if (pwd != NULL) {
Dheeraj Shettycc231012014-07-02 21:27:57 +02004001 if (strcmp(pwd->pw_name, processName) == 0) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004002 is_phone_socket = 1;
4003 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004004 RLOGE("RILD can't accept socket from process %s", pwd->pw_name);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004005 }
4006 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004007 RLOGE("Error on getpwuid() errno: %d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004008 }
4009 } else {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004010 RLOGD("Error on getsockopt() errno: %d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004011 }
4012
Howard Subd82ef12015-04-12 10:25:05 +02004013 if (!is_phone_socket) {
Dheeraj Shettycc231012014-07-02 21:27:57 +02004014 RLOGE("RILD must accept socket from %s", processName);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004015
Dheeraj Shettycc231012014-07-02 21:27:57 +02004016 close(fdCommand);
4017 fdCommand = -1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004018
Dheeraj Shettycc231012014-07-02 21:27:57 +02004019 if(NULL == sapSocket) {
4020 onCommandsSocketClosed(p_info->socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004021
Dheeraj Shettycc231012014-07-02 21:27:57 +02004022 /* start listening for new connections again */
4023 rilEventAddWakeup(p_info->listen_event);
4024 } else {
4025 sapSocket->onCommandsSocketClosed();
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004026
Dheeraj Shettycc231012014-07-02 21:27:57 +02004027 /* start listening for new connections again */
4028 rilEventAddWakeup(sapSocket->getListenEvent());
4029 }
4030
4031 return;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004032 }
4033
Howard Sue32dbfd2015-01-07 15:55:57 +08004034 ret = fcntl(fdCommand, F_SETFL, O_NONBLOCK);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004035
4036 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004037 RLOGE ("Error setting O_NONBLOCK errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004038 }
4039
Dheeraj Shettycc231012014-07-02 21:27:57 +02004040 if(NULL == sapSocket) {
4041 RLOGI("libril: new connection to %s", rilSocketIdToString(p_info->socket_id));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004042
Dheeraj Shettycc231012014-07-02 21:27:57 +02004043 p_info->fdCommand = fdCommand;
4044 p_rs = record_stream_new(p_info->fdCommand, MAX_COMMAND_BYTES);
4045 p_info->p_rs = p_rs;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004046
Dheeraj Shettycc231012014-07-02 21:27:57 +02004047 ril_event_set (p_info->commands_event, p_info->fdCommand, 1,
Howard Sue32dbfd2015-01-07 15:55:57 +08004048 p_info->processCommandsCallback, p_info);
Dheeraj Shettycc231012014-07-02 21:27:57 +02004049 rilEventAddWakeup (p_info->commands_event);
Howard Sue32dbfd2015-01-07 15:55:57 +08004050
Dheeraj Shettycc231012014-07-02 21:27:57 +02004051 onNewCommandConnect(p_info->socket_id);
4052 } else {
4053 RLOGI("libril: new connection");
Howard Sue32dbfd2015-01-07 15:55:57 +08004054
Dheeraj Shettycc231012014-07-02 21:27:57 +02004055 sapSocket->setCommandFd(fdCommand);
4056 p_rs = record_stream_new(sapSocket->getCommandFd(), MAX_COMMAND_BYTES);
4057 sClient = new socketClient(sapSocket,p_rs);
4058 ril_event_set (sapSocket->getCallbackEvent(), sapSocket->getCommandFd(), 1,
4059 sapSocket->getCommandCb(), sClient);
4060
4061 rilEventAddWakeup(sapSocket->getCallbackEvent());
4062 sapSocket->onNewCommandConnect();
4063 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004064}
4065
4066static void freeDebugCallbackArgs(int number, char **args) {
4067 for (int i = 0; i < number; i++) {
4068 if (args[i] != NULL) {
4069 free(args[i]);
4070 }
4071 }
4072 free(args);
4073}
4074
4075static void debugCallback (int fd, short flags, void *param) {
4076 int acceptFD, option;
4077 struct sockaddr_un peeraddr;
4078 socklen_t socklen = sizeof (peeraddr);
4079 int data;
4080 unsigned int qxdm_data[6];
4081 const char *deactData[1] = {"1"};
4082 char *actData[1];
4083 RIL_Dial dialData;
4084 int hangupData[1] = {1};
4085 int number;
4086 char **args;
Howard Sue32dbfd2015-01-07 15:55:57 +08004087 RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
4088 int sim_id = 0;
4089
4090 RLOGI("debugCallback for socket %s", rilSocketIdToString(socket_id));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004091
4092 acceptFD = accept (fd, (sockaddr *) &peeraddr, &socklen);
4093
4094 if (acceptFD < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004095 RLOGE ("error accepting on debug port: %d\n", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004096 return;
4097 }
4098
4099 if (recv(acceptFD, &number, sizeof(int), 0) != sizeof(int)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004100 RLOGE ("error reading on socket: number of Args: \n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004101 return;
4102 }
4103 args = (char **) malloc(sizeof(char*) * number);
4104
4105 for (int i = 0; i < number; i++) {
4106 int len;
4107 if (recv(acceptFD, &len, sizeof(int), 0) != sizeof(int)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004108 RLOGE ("error reading on socket: Len of Args: \n");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004109 freeDebugCallbackArgs(i, args);
4110 return;
4111 }
4112 // +1 for null-term
4113 args[i] = (char *) malloc((sizeof(char) * len) + 1);
4114 if (recv(acceptFD, args[i], sizeof(char) * len, 0)
4115 != (int)sizeof(char) * len) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004116 RLOGE ("error reading on socket: Args[%d] \n", i);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004117 freeDebugCallbackArgs(i, args);
4118 return;
4119 }
4120 char * buf = args[i];
4121 buf[len] = 0;
Howard Sue32dbfd2015-01-07 15:55:57 +08004122 if ((i+1) == number) {
4123 /* The last argument should be sim id 0(SIM1)~3(SIM4) */
4124 sim_id = atoi(args[i]);
4125 switch (sim_id) {
4126 case 0:
4127 socket_id = RIL_SOCKET_1;
4128 break;
4129 #if (SIM_COUNT >= 2)
4130 case 1:
4131 socket_id = RIL_SOCKET_2;
4132 break;
4133 #endif
4134 #if (SIM_COUNT >= 3)
4135 case 2:
4136 socket_id = RIL_SOCKET_3;
4137 break;
4138 #endif
4139 #if (SIM_COUNT >= 4)
4140 case 3:
4141 socket_id = RIL_SOCKET_4;
4142 break;
4143 #endif
4144 default:
4145 socket_id = RIL_SOCKET_1;
4146 break;
4147 }
4148 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004149 }
4150
4151 switch (atoi(args[0])) {
4152 case 0:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004153 RLOGI ("Connection on debug port: issuing reset.");
Howard Sue32dbfd2015-01-07 15:55:57 +08004154 issueLocalRequest(RIL_REQUEST_RESET_RADIO, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004155 break;
4156 case 1:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004157 RLOGI ("Connection on debug port: issuing radio power off.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004158 data = 0;
Howard Sue32dbfd2015-01-07 15:55:57 +08004159 issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004160 // Close the socket
Howard Subd82ef12015-04-12 10:25:05 +02004161 if (socket_id == RIL_SOCKET_1 && s_ril_param_socket.fdCommand > 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004162 close(s_ril_param_socket.fdCommand);
4163 s_ril_param_socket.fdCommand = -1;
4164 }
4165 #if (SIM_COUNT == 2)
4166 else if (socket_id == RIL_SOCKET_2 && s_ril_param_socket2.fdCommand > 0) {
4167 close(s_ril_param_socket2.fdCommand);
4168 s_ril_param_socket2.fdCommand = -1;
4169 }
4170 #endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004171 break;
4172 case 2:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004173 RLOGI ("Debug port: issuing unsolicited voice network change.");
Howard Sue32dbfd2015-01-07 15:55:57 +08004174 RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004175 break;
4176 case 3:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004177 RLOGI ("Debug port: QXDM log enable.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004178 qxdm_data[0] = 65536; // head.func_tag
4179 qxdm_data[1] = 16; // head.len
4180 qxdm_data[2] = 1; // mode: 1 for 'start logging'
4181 qxdm_data[3] = 32; // log_file_size: 32megabytes
4182 qxdm_data[4] = 0; // log_mask
4183 qxdm_data[5] = 8; // log_max_fileindex
4184 issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
Howard Sue32dbfd2015-01-07 15:55:57 +08004185 6 * sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004186 break;
4187 case 4:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004188 RLOGI ("Debug port: QXDM log disable.");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004189 qxdm_data[0] = 65536;
4190 qxdm_data[1] = 16;
4191 qxdm_data[2] = 0; // mode: 0 for 'stop logging'
4192 qxdm_data[3] = 32;
4193 qxdm_data[4] = 0;
4194 qxdm_data[5] = 8;
4195 issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
Howard Sue32dbfd2015-01-07 15:55:57 +08004196 6 * sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004197 break;
4198 case 5:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004199 RLOGI("Debug port: Radio On");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004200 data = 1;
Howard Sue32dbfd2015-01-07 15:55:57 +08004201 issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004202 sleep(2);
4203 // Set network selection automatic.
Howard Sue32dbfd2015-01-07 15:55:57 +08004204 issueLocalRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004205 break;
4206 case 6:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004207 RLOGI("Debug port: Setup Data Call, Apn :%s\n", args[1]);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004208 actData[0] = args[1];
4209 issueLocalRequest(RIL_REQUEST_SETUP_DATA_CALL, &actData,
Howard Sue32dbfd2015-01-07 15:55:57 +08004210 sizeof(actData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004211 break;
4212 case 7:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004213 RLOGI("Debug port: Deactivate Data Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004214 issueLocalRequest(RIL_REQUEST_DEACTIVATE_DATA_CALL, &deactData,
Howard Sue32dbfd2015-01-07 15:55:57 +08004215 sizeof(deactData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004216 break;
4217 case 8:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004218 RLOGI("Debug port: Dial Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004219 dialData.clir = 0;
4220 dialData.address = args[1];
Howard Sue32dbfd2015-01-07 15:55:57 +08004221 issueLocalRequest(RIL_REQUEST_DIAL, &dialData, sizeof(dialData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004222 break;
4223 case 9:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004224 RLOGI("Debug port: Answer Call");
Howard Sue32dbfd2015-01-07 15:55:57 +08004225 issueLocalRequest(RIL_REQUEST_ANSWER, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004226 break;
4227 case 10:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004228 RLOGI("Debug port: End Call");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004229 issueLocalRequest(RIL_REQUEST_HANGUP, &hangupData,
Howard Sue32dbfd2015-01-07 15:55:57 +08004230 sizeof(hangupData), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004231 break;
4232 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004233 RLOGE ("Invalid request");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004234 break;
4235 }
4236 freeDebugCallbackArgs(number, args);
4237 close(acceptFD);
4238}
4239
4240
4241static void userTimerCallback (int fd, short flags, void *param) {
4242 UserCallbackInfo *p_info;
4243
4244 p_info = (UserCallbackInfo *)param;
4245
4246 p_info->p_callback(p_info->userParam);
4247
4248
4249 // FIXME generalize this...there should be a cancel mechanism
4250 if (s_last_wake_timeout_info != NULL && s_last_wake_timeout_info == p_info) {
4251 s_last_wake_timeout_info = NULL;
4252 }
4253
4254 free(p_info);
4255}
4256
4257
4258static void *
4259eventLoop(void *param) {
4260 int ret;
4261 int filedes[2];
4262
4263 ril_event_init();
4264
4265 pthread_mutex_lock(&s_startupMutex);
4266
4267 s_started = 1;
4268 pthread_cond_broadcast(&s_startupCond);
4269
4270 pthread_mutex_unlock(&s_startupMutex);
4271
4272 ret = pipe(filedes);
4273
4274 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004275 RLOGE("Error in pipe() errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004276 return NULL;
4277 }
4278
4279 s_fdWakeupRead = filedes[0];
4280 s_fdWakeupWrite = filedes[1];
4281
4282 fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
4283
4284 ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
4285 processWakeupCallback, NULL);
4286
4287 rilEventAddWakeup (&s_wakeupfd_event);
4288
4289 // Only returns on error
4290 ril_event_loop();
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004291 RLOGE ("error in event_loop_base errno:%d", errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004292 // kill self to restart on error
4293 kill(0, SIGKILL);
4294
4295 return NULL;
4296}
4297
4298extern "C" void
4299RIL_startEventLoop(void) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004300 /* spin up eventLoop thread and wait for it to get started */
4301 s_started = 0;
4302 pthread_mutex_lock(&s_startupMutex);
4303
Howard Sue32dbfd2015-01-07 15:55:57 +08004304 pthread_attr_t attr;
4305 pthread_attr_init(&attr);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004306 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
Howard Sue32dbfd2015-01-07 15:55:57 +08004307
4308 int result = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
4309 if (result != 0) {
4310 RLOGE("Failed to create dispatch thread: %s", strerror(result));
4311 goto done;
4312 }
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004313
4314 while (s_started == 0) {
4315 pthread_cond_wait(&s_startupCond, &s_startupMutex);
4316 }
4317
Howard Sue32dbfd2015-01-07 15:55:57 +08004318done:
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004319 pthread_mutex_unlock(&s_startupMutex);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004320}
4321
4322// Used for testing purpose only.
4323extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) {
4324 memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
4325}
4326
Howard Sue32dbfd2015-01-07 15:55:57 +08004327static void startListen(RIL_SOCKET_ID socket_id, SocketListenParam* socket_listen_p) {
4328 int fdListen = -1;
4329 int ret;
4330 char socket_name[10];
4331
4332 memset(socket_name, 0, sizeof(char)*10);
4333
4334 switch(socket_id) {
4335 case RIL_SOCKET_1:
4336 strncpy(socket_name, RIL_getRilSocketName(), 9);
4337 break;
4338 #if (SIM_COUNT >= 2)
4339 case RIL_SOCKET_2:
4340 strncpy(socket_name, SOCKET2_NAME_RIL, 9);
4341 break;
4342 #endif
4343 #if (SIM_COUNT >= 3)
4344 case RIL_SOCKET_3:
4345 strncpy(socket_name, SOCKET3_NAME_RIL, 9);
4346 break;
4347 #endif
4348 #if (SIM_COUNT >= 4)
4349 case RIL_SOCKET_4:
4350 strncpy(socket_name, SOCKET4_NAME_RIL, 9);
4351 break;
4352 #endif
4353 default:
4354 RLOGE("Socket id is wrong!!");
4355 return;
4356 }
4357
4358 RLOGI("Start to listen %s", rilSocketIdToString(socket_id));
4359
4360 fdListen = android_get_control_socket(socket_name);
4361 if (fdListen < 0) {
4362 RLOGE("Failed to get socket %s", socket_name);
4363 exit(-1);
4364 }
4365
4366 ret = listen(fdListen, 4);
4367
4368 if (ret < 0) {
4369 RLOGE("Failed to listen on control socket '%d': %s",
4370 fdListen, strerror(errno));
4371 exit(-1);
4372 }
4373 socket_listen_p->fdListen = fdListen;
4374
4375 /* note: non-persistent so we can accept only one connection at a time */
4376 ril_event_set (socket_listen_p->listen_event, fdListen, false,
4377 listenCallback, socket_listen_p);
4378
4379 rilEventAddWakeup (socket_listen_p->listen_event);
4380}
4381
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004382extern "C" void
4383RIL_register (const RIL_RadioFunctions *callbacks) {
4384 int ret;
4385 int flags;
4386
Howard Sue32dbfd2015-01-07 15:55:57 +08004387 RLOGI("SIM_COUNT: %d", SIM_COUNT);
4388
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004389 if (callbacks == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004390 RLOGE("RIL_register: RIL_RadioFunctions * null");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004391 return;
4392 }
4393 if (callbacks->version < RIL_VERSION_MIN) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004394 RLOGE("RIL_register: version %d is to old, min version is %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004395 callbacks->version, RIL_VERSION_MIN);
4396 return;
4397 }
4398 if (callbacks->version > RIL_VERSION) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004399 RLOGE("RIL_register: version %d is too new, max version is %d",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004400 callbacks->version, RIL_VERSION);
4401 return;
4402 }
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004403 RLOGE("RIL_register: RIL version %d", callbacks->version);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004404
4405 if (s_registerCalled > 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004406 RLOGE("RIL_register has been called more than once. "
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004407 "Subsequent call ignored");
4408 return;
4409 }
4410
4411 memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
4412
Howard Sue32dbfd2015-01-07 15:55:57 +08004413 /* Initialize socket1 parameters */
4414 s_ril_param_socket = {
4415 RIL_SOCKET_1, /* socket_id */
4416 -1, /* fdListen */
4417 -1, /* fdCommand */
4418 PHONE_PROCESS, /* processName */
4419 &s_commands_event, /* commands_event */
4420 &s_listen_event, /* listen_event */
4421 processCommandsCallback, /* processCommandsCallback */
4422 NULL /* p_rs */
4423 };
4424
4425#if (SIM_COUNT >= 2)
4426 s_ril_param_socket2 = {
4427 RIL_SOCKET_2, /* socket_id */
4428 -1, /* fdListen */
4429 -1, /* fdCommand */
4430 PHONE_PROCESS, /* processName */
4431 &s_commands_event_socket2, /* commands_event */
4432 &s_listen_event_socket2, /* listen_event */
4433 processCommandsCallback, /* processCommandsCallback */
4434 NULL /* p_rs */
4435 };
4436#endif
4437
4438#if (SIM_COUNT >= 3)
4439 s_ril_param_socket3 = {
4440 RIL_SOCKET_3, /* socket_id */
4441 -1, /* fdListen */
4442 -1, /* fdCommand */
4443 PHONE_PROCESS, /* processName */
4444 &s_commands_event_socket3, /* commands_event */
4445 &s_listen_event_socket3, /* listen_event */
4446 processCommandsCallback, /* processCommandsCallback */
4447 NULL /* p_rs */
4448 };
4449#endif
4450
4451#if (SIM_COUNT >= 4)
4452 s_ril_param_socket4 = {
4453 RIL_SOCKET_4, /* socket_id */
4454 -1, /* fdListen */
4455 -1, /* fdCommand */
4456 PHONE_PROCESS, /* processName */
4457 &s_commands_event_socket4, /* commands_event */
4458 &s_listen_event_socket4, /* listen_event */
4459 processCommandsCallback, /* processCommandsCallback */
4460 NULL /* p_rs */
4461 };
4462#endif
4463
Howard Subd82ef12015-04-12 10:25:05 +02004464
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004465 s_registerCalled = 1;
4466
Howard Sue32dbfd2015-01-07 15:55:57 +08004467 RLOGI("s_registerCalled flag set, %d", s_started);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004468 // Little self-check
4469
4470 for (int i = 0; i < (int)NUM_ELEMS(s_commands); i++) {
4471 assert(i == s_commands[i].requestNumber);
4472 }
4473
Howard Subd82ef12015-04-12 10:25:05 +02004474 for (int i = 0; i < (int)NUM_ELEMS(s_commands_v); i++) {
4475 assert(i + RIL_VENDOR_COMMANDS_OFFSET == s_commands[i].requestNumber);
4476 }
4477
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004478 for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses); i++) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004479 assert(i + RIL_UNSOL_RESPONSE_BASE
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004480 == s_unsolResponses[i].requestNumber);
4481 }
4482
Howard Subd82ef12015-04-12 10:25:05 +02004483 for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses_v); i++) {
4484 assert(i + RIL_UNSOL_RESPONSE_BASE + RIL_VENDOR_COMMANDS_OFFSET
4485 == s_unsolResponses[i].requestNumber);
4486 }
4487
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004488 // New rild impl calls RIL_startEventLoop() first
4489 // old standalone impl wants it here.
4490
4491 if (s_started == 0) {
4492 RIL_startEventLoop();
4493 }
4494
Howard Sue32dbfd2015-01-07 15:55:57 +08004495 // start listen socket1
4496 startListen(RIL_SOCKET_1, &s_ril_param_socket);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004497
Howard Sue32dbfd2015-01-07 15:55:57 +08004498#if (SIM_COUNT >= 2)
4499 // start listen socket2
4500 startListen(RIL_SOCKET_2, &s_ril_param_socket2);
4501#endif /* (SIM_COUNT == 2) */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004502
Howard Sue32dbfd2015-01-07 15:55:57 +08004503#if (SIM_COUNT >= 3)
4504 // start listen socket3
4505 startListen(RIL_SOCKET_3, &s_ril_param_socket3);
4506#endif /* (SIM_COUNT == 3) */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004507
Howard Sue32dbfd2015-01-07 15:55:57 +08004508#if (SIM_COUNT >= 4)
4509 // start listen socket4
4510 startListen(RIL_SOCKET_4, &s_ril_param_socket4);
4511#endif /* (SIM_COUNT == 4) */
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004512
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004513
4514#if 1
4515 // start debug interface socket
4516
Howard Sue32dbfd2015-01-07 15:55:57 +08004517 char *inst = NULL;
4518 if (strlen(RIL_getRilSocketName()) >= strlen(SOCKET_NAME_RIL)) {
4519 inst = RIL_getRilSocketName() + strlen(SOCKET_NAME_RIL);
4520 }
4521
4522 char rildebug[MAX_DEBUG_SOCKET_NAME_LENGTH] = SOCKET_NAME_RIL_DEBUG;
4523 if (inst != NULL) {
Andreas Schneider3063dc12015-04-13 23:04:05 +02004524 snprintf(rildebug, sizeof(rildebug), "%s%s", SOCKET_NAME_RIL_DEBUG, inst);
Howard Sue32dbfd2015-01-07 15:55:57 +08004525 }
4526
4527 s_fdDebug = android_get_control_socket(rildebug);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004528 if (s_fdDebug < 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004529 RLOGE("Failed to get socket : %s errno:%d", rildebug, errno);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004530 exit(-1);
4531 }
4532
4533 ret = listen(s_fdDebug, 4);
4534
4535 if (ret < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004536 RLOGE("Failed to listen on ril debug socket '%d': %s",
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004537 s_fdDebug, strerror(errno));
4538 exit(-1);
4539 }
4540
4541 ril_event_set (&s_debug_event, s_fdDebug, true,
4542 debugCallback, NULL);
4543
4544 rilEventAddWakeup (&s_debug_event);
4545#endif
4546
4547}
4548
Dheeraj Shettycc231012014-07-02 21:27:57 +02004549extern "C" void
4550RIL_register_socket (RIL_RadioFunctions *(*Init)(const struct RIL_Env *, int, char **),RIL_SOCKET_TYPE socketType, int argc, char **argv) {
4551
4552 RIL_RadioFunctions* UimFuncs = NULL;
4553
4554 if(Init) {
4555 UimFuncs = Init(&RilSapSocket::uimRilEnv, argc, argv);
4556
4557 switch(socketType) {
4558 case RIL_SAP_SOCKET:
4559 RilSapSocket::initSapSocket("sap_uim_socket1", UimFuncs);
4560
4561#if (SIM_COUNT >= 2)
4562 RilSapSocket::initSapSocket("sap_uim_socket2", UimFuncs);
4563#endif
4564
4565#if (SIM_COUNT >= 3)
4566 RilSapSocket::initSapSocket("sap_uim_socket3", UimFuncs);
4567#endif
4568
4569#if (SIM_COUNT >= 4)
4570 RilSapSocket::initSapSocket("sap_uim_socket4", UimFuncs);
4571#endif
4572 }
4573 }
4574}
4575
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004576static int
4577checkAndDequeueRequestInfo(struct RequestInfo *pRI) {
4578 int ret = 0;
Howard Sue32dbfd2015-01-07 15:55:57 +08004579 /* Hook for current context
4580 pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
4581 pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
4582 /* pendingRequestsHook refer to &s_pendingRequests */
4583 RequestInfo ** pendingRequestsHook = &s_pendingRequests;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004584
4585 if (pRI == NULL) {
4586 return 0;
4587 }
4588
Howard Sue32dbfd2015-01-07 15:55:57 +08004589#if (SIM_COUNT >= 2)
4590 if (pRI->socket_id == RIL_SOCKET_2) {
4591 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
4592 pendingRequestsHook = &s_pendingRequests_socket2;
4593 }
4594#if (SIM_COUNT >= 3)
4595 if (pRI->socket_id == RIL_SOCKET_3) {
4596 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
4597 pendingRequestsHook = &s_pendingRequests_socket3;
4598 }
4599#endif
4600#if (SIM_COUNT >= 4)
4601 if (pRI->socket_id == RIL_SOCKET_4) {
4602 pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
4603 pendingRequestsHook = &s_pendingRequests_socket4;
4604 }
4605#endif
4606#endif
4607 pthread_mutex_lock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004608
Howard Sue32dbfd2015-01-07 15:55:57 +08004609 for(RequestInfo **ppCur = pendingRequestsHook
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004610 ; *ppCur != NULL
4611 ; ppCur = &((*ppCur)->p_next)
4612 ) {
4613 if (pRI == *ppCur) {
4614 ret = 1;
4615
4616 *ppCur = (*ppCur)->p_next;
4617 break;
4618 }
4619 }
4620
Howard Sue32dbfd2015-01-07 15:55:57 +08004621 pthread_mutex_unlock(pendingRequestsMutexHook);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004622
4623 return ret;
4624}
4625
4626
4627extern "C" void
4628RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
4629 RequestInfo *pRI;
4630 int ret;
Howard Sue32dbfd2015-01-07 15:55:57 +08004631 int fd = s_ril_param_socket.fdCommand;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004632 size_t errorOffset;
Howard Sue32dbfd2015-01-07 15:55:57 +08004633 RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004634
4635 pRI = (RequestInfo *)t;
4636
4637 if (!checkAndDequeueRequestInfo(pRI)) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004638 RLOGE ("RIL_onRequestComplete: invalid RIL_Token");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004639 return;
4640 }
4641
Howard Sue32dbfd2015-01-07 15:55:57 +08004642 socket_id = pRI->socket_id;
4643#if (SIM_COUNT >= 2)
4644 if (socket_id == RIL_SOCKET_2) {
4645 fd = s_ril_param_socket2.fdCommand;
4646 }
4647#if (SIM_COUNT >= 3)
4648 if (socket_id == RIL_SOCKET_3) {
4649 fd = s_ril_param_socket3.fdCommand;
4650 }
4651#endif
4652#if (SIM_COUNT >= 4)
4653 if (socket_id == RIL_SOCKET_4) {
4654 fd = s_ril_param_socket4.fdCommand;
4655 }
4656#endif
4657#endif
4658 RLOGD("RequestComplete, %s", rilSocketIdToString(socket_id));
4659
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004660 if (pRI->local > 0) {
4661 // Locally issued command...void only!
4662 // response does not go back up the command socket
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004663 RLOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004664
4665 goto done;
4666 }
4667
4668 appendPrintBuf("[%04d]< %s",
4669 pRI->token, requestToString(pRI->pCI->requestNumber));
4670
4671 if (pRI->cancelled == 0) {
4672 Parcel p;
4673
4674 p.writeInt32 (RESPONSE_SOLICITED);
4675 p.writeInt32 (pRI->token);
4676 errorOffset = p.dataPosition();
4677
4678 p.writeInt32 (e);
4679
4680 if (response != NULL) {
4681 // there is a response payload, no matter success or not.
4682 ret = pRI->pCI->responseFunction(p, response, responselen);
4683
4684 /* if an error occurred, rewind and mark it */
4685 if (ret != 0) {
Howard Sue32dbfd2015-01-07 15:55:57 +08004686 RLOGE ("responseFunction error, ret %d", ret);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004687 p.setDataPosition(errorOffset);
4688 p.writeInt32 (ret);
4689 }
4690 }
4691
4692 if (e != RIL_E_SUCCESS) {
4693 appendPrintBuf("%s fails by %s", printBuf, failCauseToString(e));
4694 }
4695
Howard Sue32dbfd2015-01-07 15:55:57 +08004696 if (fd < 0) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004697 RLOGD ("RIL onRequestComplete: Command channel closed");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004698 }
Howard Sue32dbfd2015-01-07 15:55:57 +08004699 sendResponse(p, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004700 }
4701
4702done:
4703 free(pRI);
4704}
4705
Howard Subd82ef12015-04-12 10:25:05 +02004706
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004707static void
4708grabPartialWakeLock() {
4709 acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
4710}
4711
4712static void
4713releaseWakeLock() {
4714 release_wake_lock(ANDROID_WAKE_LOCK_NAME);
4715}
4716
4717/**
4718 * Timer callback to put us back to sleep before the default timeout
4719 */
4720static void
4721wakeTimeoutCallback (void *param) {
4722 // We're using "param != NULL" as a cancellation mechanism
4723 if (param == NULL) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004724 releaseWakeLock();
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004725 }
4726}
4727
4728static int
4729decodeVoiceRadioTechnology (RIL_RadioState radioState) {
4730 switch (radioState) {
4731 case RADIO_STATE_SIM_NOT_READY:
4732 case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
4733 case RADIO_STATE_SIM_READY:
4734 return RADIO_TECH_UMTS;
4735
4736 case RADIO_STATE_RUIM_NOT_READY:
4737 case RADIO_STATE_RUIM_READY:
4738 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
4739 case RADIO_STATE_NV_NOT_READY:
4740 case RADIO_STATE_NV_READY:
4741 return RADIO_TECH_1xRTT;
4742
4743 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004744 RLOGD("decodeVoiceRadioTechnology: Invoked with incorrect RadioState");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004745 return -1;
4746 }
4747}
4748
4749static int
4750decodeCdmaSubscriptionSource (RIL_RadioState radioState) {
4751 switch (radioState) {
4752 case RADIO_STATE_SIM_NOT_READY:
4753 case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
4754 case RADIO_STATE_SIM_READY:
4755 case RADIO_STATE_RUIM_NOT_READY:
4756 case RADIO_STATE_RUIM_READY:
4757 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
4758 return CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM;
4759
4760 case RADIO_STATE_NV_NOT_READY:
4761 case RADIO_STATE_NV_READY:
4762 return CDMA_SUBSCRIPTION_SOURCE_NV;
4763
4764 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004765 RLOGD("decodeCdmaSubscriptionSource: Invoked with incorrect RadioState");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004766 return -1;
4767 }
4768}
4769
4770static int
4771decodeSimStatus (RIL_RadioState radioState) {
4772 switch (radioState) {
4773 case RADIO_STATE_SIM_NOT_READY:
4774 case RADIO_STATE_RUIM_NOT_READY:
4775 case RADIO_STATE_NV_NOT_READY:
4776 case RADIO_STATE_NV_READY:
4777 return -1;
4778 case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
4779 case RADIO_STATE_SIM_READY:
4780 case RADIO_STATE_RUIM_READY:
4781 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
4782 return radioState;
4783 default:
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004784 RLOGD("decodeSimStatus: Invoked with incorrect RadioState");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004785 return -1;
4786 }
4787}
4788
4789static bool is3gpp2(int radioTech) {
4790 switch (radioTech) {
4791 case RADIO_TECH_IS95A:
4792 case RADIO_TECH_IS95B:
4793 case RADIO_TECH_1xRTT:
4794 case RADIO_TECH_EVDO_0:
4795 case RADIO_TECH_EVDO_A:
4796 case RADIO_TECH_EVDO_B:
4797 case RADIO_TECH_EHRPD:
4798 return true;
4799 default:
4800 return false;
4801 }
4802}
4803
4804/* If RIL sends SIM states or RUIM states, store the voice radio
4805 * technology and subscription source information so that they can be
4806 * returned when telephony framework requests them
4807 */
4808static RIL_RadioState
Howard Subd82ef12015-04-12 10:25:05 +02004809processRadioState(RIL_RadioState newRadioState, RIL_SOCKET_ID socket_id) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004810
4811 if((newRadioState > RADIO_STATE_UNAVAILABLE) && (newRadioState < RADIO_STATE_ON)) {
4812 int newVoiceRadioTech;
4813 int newCdmaSubscriptionSource;
4814 int newSimStatus;
4815
4816 /* This is old RIL. Decode Subscription source and Voice Radio Technology
4817 from Radio State and send change notifications if there has been a change */
4818 newVoiceRadioTech = decodeVoiceRadioTechnology(newRadioState);
4819 if(newVoiceRadioTech != voiceRadioTech) {
4820 voiceRadioTech = newVoiceRadioTech;
Howard Sue32dbfd2015-01-07 15:55:57 +08004821 RIL_UNSOL_RESPONSE(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED,
4822 &voiceRadioTech, sizeof(voiceRadioTech), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004823 }
4824 if(is3gpp2(newVoiceRadioTech)) {
4825 newCdmaSubscriptionSource = decodeCdmaSubscriptionSource(newRadioState);
4826 if(newCdmaSubscriptionSource != cdmaSubscriptionSource) {
4827 cdmaSubscriptionSource = newCdmaSubscriptionSource;
Howard Sue32dbfd2015-01-07 15:55:57 +08004828 RIL_UNSOL_RESPONSE(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED,
4829 &cdmaSubscriptionSource, sizeof(cdmaSubscriptionSource), socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004830 }
4831 }
4832 newSimStatus = decodeSimStatus(newRadioState);
4833 if(newSimStatus != simRuimStatus) {
4834 simRuimStatus = newSimStatus;
Howard Sue32dbfd2015-01-07 15:55:57 +08004835 RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0, socket_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004836 }
4837
4838 /* Send RADIO_ON to telephony */
4839 newRadioState = RADIO_STATE_ON;
4840 }
4841
4842 return newRadioState;
4843}
4844
Howard Subd82ef12015-04-12 10:25:05 +02004845
Howard Sue32dbfd2015-01-07 15:55:57 +08004846#if defined(ANDROID_MULTI_SIM)
4847extern "C"
Andreas Schneider47b2d962015-04-13 22:54:49 +02004848void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
Howard Sue32dbfd2015-01-07 15:55:57 +08004849 size_t datalen, RIL_SOCKET_ID socket_id)
4850#else
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004851extern "C"
Andreas Schneider47b2d962015-04-13 22:54:49 +02004852void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004853 size_t datalen)
Howard Sue32dbfd2015-01-07 15:55:57 +08004854#endif
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004855{
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004856 int ret;
4857 int64_t timeReceived = 0;
4858 bool shouldScheduleTimeout = false;
4859 RIL_RadioState newState;
Howard Sue32dbfd2015-01-07 15:55:57 +08004860 RIL_SOCKET_ID soc_id = RIL_SOCKET_1;
Howard Subd82ef12015-04-12 10:25:05 +02004861 UnsolResponseInfo *pRI = NULL;
Howard Sue32dbfd2015-01-07 15:55:57 +08004862
4863#if defined(ANDROID_MULTI_SIM)
4864 soc_id = socket_id;
4865#endif
4866
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004867
4868 if (s_registerCalled == 0) {
4869 // Ignore RIL_onUnsolicitedResponse before RIL_register
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004870 RLOGW("RIL_onUnsolicitedResponse called before RIL_register");
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004871 return;
4872 }
Howard Sue32dbfd2015-01-07 15:55:57 +08004873
Howard Subd82ef12015-04-12 10:25:05 +02004874 /* Hack to include Samsung responses */
4875 if (unsolResponse > RIL_VENDOR_COMMANDS_OFFSET + RIL_UNSOL_RESPONSE_BASE) {
4876 int index = unsolResponse - RIL_VENDOR_COMMANDS_OFFSET - RIL_UNSOL_RESPONSE_BASE;
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004877
Howard Subd82ef12015-04-12 10:25:05 +02004878 RLOGD("SAMSUNG: unsolResponse=%d, unsolResponseIndex=%d", unsolResponse, index);
4879
4880 if (index < (int32_t)NUM_ELEMS(s_unsolResponses_v))
4881 pRI = &s_unsolResponses_v[index];
4882 } else {
4883 int index = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
4884 if (index < (int32_t)NUM_ELEMS(s_unsolResponses))
4885 pRI = &s_unsolResponses[index];
4886 }
4887
4888 if (pRI == NULL || pRI->responseFunction == NULL) {
XpLoDWilDba5c6a32013-07-27 21:12:19 +02004889 RLOGE("unsupported unsolicited response code %d", unsolResponse);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004890 return;
4891 }
4892
4893 // Grab a wake lock if needed for this reponse,
4894 // as we exit we'll either release it immediately
4895 // or set a timer to release it later.
Howard Subd82ef12015-04-12 10:25:05 +02004896 switch (pRI->wakeType) {
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004897 case WAKE_PARTIAL:
4898 grabPartialWakeLock();
4899 shouldScheduleTimeout = true;
4900 break;
4901
4902 case DONT_WAKE:
4903 default:
4904 // No wake lock is grabed so don't set timeout
4905 shouldScheduleTimeout = false;
4906 break;
4907 }
4908
4909 // Mark the time this was received, doing this
4910 // after grabing the wakelock incase getting
4911 // the elapsedRealTime might cause us to goto
4912 // sleep.
4913 if (unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
4914 timeReceived = elapsedRealtime();
4915 }
4916
4917 appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
4918
4919 Parcel p;
4920
4921 p.writeInt32 (RESPONSE_UNSOLICITED);
4922 p.writeInt32 (unsolResponse);
4923
Howard Subd82ef12015-04-12 10:25:05 +02004924 ret = pRI->responseFunction(p, const_cast<void*>(data), datalen);
4925
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004926 if (ret != 0) {
4927 // Problem with the response. Don't continue;
4928 goto error_exit;
4929 }
4930
4931 // some things get more payload
4932 switch(unsolResponse) {
4933 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
Howard Sue32dbfd2015-01-07 15:55:57 +08004934 newState = processRadioState(CALL_ONSTATEREQUEST(soc_id), soc_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004935 p.writeInt32(newState);
4936 appendPrintBuf("%s {%s}", printBuf,
Howard Sue32dbfd2015-01-07 15:55:57 +08004937 radioStateToString(CALL_ONSTATEREQUEST(soc_id)));
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004938 break;
4939
4940
4941 case RIL_UNSOL_NITZ_TIME_RECEIVED:
4942 // Store the time that this was received so the
4943 // handler of this message can account for
4944 // the time it takes to arrive and process. In
4945 // particular the system has been known to sleep
4946 // before this message can be processed.
4947 p.writeInt64(timeReceived);
4948 break;
4949 }
4950
Howard Sue32dbfd2015-01-07 15:55:57 +08004951 RLOGI("%s UNSOLICITED: %s length:%d", rilSocketIdToString(soc_id), requestToString(unsolResponse), p.dataSize());
4952 ret = sendResponse(p, soc_id);
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02004953 if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
4954
4955 // Unfortunately, NITZ time is not poll/update like everything
4956 // else in the system. So, if the upstream client isn't connected,
4957 // keep a copy of the last NITZ response (with receive time noted
4958 // above) around so we can deliver it when it is connected
4959
4960 if (s_lastNITZTimeData != NULL) {
4961 free (s_lastNITZTimeData);
4962 s_lastNITZTimeData = NULL;
4963 }
4964
4965 s_lastNITZTimeData = malloc(p.dataSize());
4966 s_lastNITZTimeDataSize = p.dataSize();
4967 memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
4968 }
4969
4970 // For now, we automatically go back to sleep after TIMEVAL_WAKE_TIMEOUT
4971 // FIXME The java code should handshake here to release wake lock
4972
4973 if (shouldScheduleTimeout) {
4974 // Cancel the previous request
4975 if (s_last_wake_timeout_info != NULL) {
4976 s_last_wake_timeout_info->userParam = (void *)1;
4977 }
4978
4979 s_last_wake_timeout_info
4980 = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
4981 &TIMEVAL_WAKE_TIMEOUT);
4982 }
4983
4984 // Normal exit
4985 return;
4986
4987error_exit:
4988 if (shouldScheduleTimeout) {
4989 releaseWakeLock();
4990 }
4991}
4992
4993/** FIXME generalize this if you track UserCAllbackInfo, clear it
4994 when the callback occurs
4995*/
4996static UserCallbackInfo *
4997internalRequestTimedCallback (RIL_TimedCallback callback, void *param,
4998 const struct timeval *relativeTime)
4999{
5000 struct timeval myRelativeTime;
5001 UserCallbackInfo *p_info;
5002
5003 p_info = (UserCallbackInfo *) malloc (sizeof(UserCallbackInfo));
5004
5005 p_info->p_callback = callback;
5006 p_info->userParam = param;
5007
5008 if (relativeTime == NULL) {
5009 /* treat null parameter as a 0 relative time */
5010 memset (&myRelativeTime, 0, sizeof(myRelativeTime));
5011 } else {
5012 /* FIXME I think event_add's tv param is really const anyway */
5013 memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime));
5014 }
5015
5016 ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info);
5017
5018 ril_timer_add(&(p_info->event), &myRelativeTime);
5019
5020 triggerEvLoop();
5021 return p_info;
5022}
5023
5024
5025extern "C" void
5026RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
5027 const struct timeval *relativeTime) {
5028 internalRequestTimedCallback (callback, param, relativeTime);
5029}
5030
5031const char *
5032failCauseToString(RIL_Errno e) {
5033 switch(e) {
5034 case RIL_E_SUCCESS: return "E_SUCCESS";
XpLoDWilDba5c6a32013-07-27 21:12:19 +02005035 case RIL_E_RADIO_NOT_AVAILABLE: return "E_RADIO_NOT_AVAILABLE";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005036 case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE";
5037 case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT";
5038 case RIL_E_SIM_PIN2: return "E_SIM_PIN2";
5039 case RIL_E_SIM_PUK2: return "E_SIM_PUK2";
5040 case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED";
5041 case RIL_E_CANCELLED: return "E_CANCELLED";
5042 case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL";
5043 case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW";
5044 case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY";
5045 case RIL_E_SIM_ABSENT:return "E_SIM_ABSENT";
5046 case RIL_E_ILLEGAL_SIM_OR_ME:return "E_ILLEGAL_SIM_OR_ME";
5047#ifdef FEATURE_MULTIMODE_ANDROID
5048 case RIL_E_SUBSCRIPTION_NOT_AVAILABLE:return "E_SUBSCRIPTION_NOT_AVAILABLE";
5049 case RIL_E_MODE_NOT_SUPPORTED:return "E_MODE_NOT_SUPPORTED";
5050#endif
5051 default: return "<unknown error>";
5052 }
5053}
5054
5055const char *
5056radioStateToString(RIL_RadioState s) {
5057 switch(s) {
5058 case RADIO_STATE_OFF: return "RADIO_OFF";
5059 case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE";
5060 case RADIO_STATE_SIM_NOT_READY: return "RADIO_SIM_NOT_READY";
5061 case RADIO_STATE_SIM_LOCKED_OR_ABSENT: return "RADIO_SIM_LOCKED_OR_ABSENT";
5062 case RADIO_STATE_SIM_READY: return "RADIO_SIM_READY";
5063 case RADIO_STATE_RUIM_NOT_READY:return"RADIO_RUIM_NOT_READY";
5064 case RADIO_STATE_RUIM_READY:return"RADIO_RUIM_READY";
5065 case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:return"RADIO_RUIM_LOCKED_OR_ABSENT";
5066 case RADIO_STATE_NV_NOT_READY:return"RADIO_NV_NOT_READY";
5067 case RADIO_STATE_NV_READY:return"RADIO_NV_READY";
5068 case RADIO_STATE_ON:return"RADIO_ON";
5069 default: return "<unknown state>";
5070 }
5071}
5072
5073const char *
5074callStateToString(RIL_CallState s) {
5075 switch(s) {
5076 case RIL_CALL_ACTIVE : return "ACTIVE";
5077 case RIL_CALL_HOLDING: return "HOLDING";
5078 case RIL_CALL_DIALING: return "DIALING";
5079 case RIL_CALL_ALERTING: return "ALERTING";
5080 case RIL_CALL_INCOMING: return "INCOMING";
5081 case RIL_CALL_WAITING: return "WAITING";
5082 default: return "<unknown state>";
5083 }
5084}
5085
5086const char *
5087requestToString(int request) {
5088/*
5089 cat libs/telephony/ril_commands.h \
5090 | egrep "^ *{RIL_" \
5091 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
5092
5093
5094 cat libs/telephony/ril_unsol_commands.h \
5095 | egrep "^ *{RIL_" \
5096 | sed -re 's/\{RIL_([^,]+),([^}]+).+/case RIL_\1: return "\1";/'
5097
5098*/
5099 switch(request) {
5100 case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
5101 case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
5102 case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
5103 case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
5104 case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
5105 case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
5106 case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
5107 case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
5108 case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
5109 case RIL_REQUEST_DIAL: return "DIAL";
5110 case RIL_REQUEST_DIAL_EMERGENCY: return "DIAL";
5111 case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
5112 case RIL_REQUEST_HANGUP: return "HANGUP";
5113 case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
5114 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
5115 case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
5116 case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
5117 case RIL_REQUEST_UDUB: return "UDUB";
5118 case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
5119 case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
5120 case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
5121 case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
5122 case RIL_REQUEST_OPERATOR: return "OPERATOR";
5123 case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
5124 case RIL_REQUEST_DTMF: return "DTMF";
5125 case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
5126 case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
5127 case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
5128 case RIL_REQUEST_SIM_IO: return "SIM_IO";
5129 case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
5130 case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
5131 case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
5132 case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
5133 case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
5134 case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
5135 case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
5136 case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
5137 case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
5138 case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
5139 case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
5140 case RIL_REQUEST_ANSWER: return "ANSWER";
5141 case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
5142 case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
5143 case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
5144 case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
5145 case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
5146 case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
5147 case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
5148 case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
5149 case RIL_REQUEST_DTMF_START: return "DTMF_START";
5150 case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
5151 case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
5152 case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
5153 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE";
5154 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE";
5155 case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS";
5156 case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
5157 case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
5158 case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
5159 case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
5160 case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
5161 case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
5162 case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
5163 case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
5164 case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
5165 case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
5166 case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE";
5167 case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE";
5168 case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND";
5169 case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE";
5170 case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
5171 case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
5172 case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER";
5173 case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES";
XpLoDWilDba5c6a32013-07-27 21:12:19 +02005174 case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:return"CDMA_SET_SUBSCRIPTION_SOURCE";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005175 case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:return"CDMA_SET_ROAMING_PREFERENCE";
5176 case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:return"CDMA_QUERY_ROAMING_PREFERENCE";
5177 case RIL_REQUEST_SET_TTY_MODE:return"SET_TTY_MODE";
5178 case RIL_REQUEST_QUERY_TTY_MODE:return"QUERY_TTY_MODE";
5179 case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
5180 case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
5181 case RIL_REQUEST_CDMA_FLASH:return"CDMA_FLASH";
5182 case RIL_REQUEST_CDMA_BURST_DTMF:return"CDMA_BURST_DTMF";
5183 case RIL_REQUEST_CDMA_SEND_SMS:return"CDMA_SEND_SMS";
5184 case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:return"CDMA_SMS_ACKNOWLEDGE";
5185 case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG:return"GSM_GET_BROADCAST_SMS_CONFIG";
5186 case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG:return"GSM_SET_BROADCAST_SMS_CONFIG";
5187 case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG:return "CDMA_GET_BROADCAST_SMS_CONFIG";
5188 case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG:return "CDMA_SET_BROADCAST_SMS_CONFIG";
5189 case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION:return "CDMA_SMS_BROADCAST_ACTIVATION";
Ethan Chend6e30652013-08-04 22:49:56 -07005190 case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return"CDMA_VALIDATE_AND_WRITE_AKEY";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005191 case RIL_REQUEST_CDMA_SUBSCRIPTION: return"CDMA_SUBSCRIPTION";
5192 case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "CDMA_WRITE_SMS_TO_RUIM";
5193 case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "CDMA_DELETE_SMS_ON_RUIM";
5194 case RIL_REQUEST_DEVICE_IDENTITY: return "DEVICE_IDENTITY";
5195 case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "EXIT_EMERGENCY_CALLBACK_MODE";
5196 case RIL_REQUEST_GET_SMSC_ADDRESS: return "GET_SMSC_ADDRESS";
5197 case RIL_REQUEST_SET_SMSC_ADDRESS: return "SET_SMSC_ADDRESS";
5198 case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "REPORT_SMS_MEMORY_STATUS";
5199 case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "REPORT_STK_SERVICE_IS_RUNNING";
5200 case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "CDMA_GET_SUBSCRIPTION_SOURCE";
5201 case RIL_REQUEST_ISIM_AUTHENTICATION: return "ISIM_AUTHENTICATION";
5202 case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
5203 case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
5204 case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH";
XpLoDWilDba5c6a32013-07-27 21:12:19 +02005205 case RIL_REQUEST_GET_CELL_INFO_LIST: return"GET_CELL_INFO_LIST";
5206 case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return"SET_UNSOL_CELL_INFO_LIST_RATE";
Andrew Jiangca4a9a02014-01-18 18:04:08 -05005207 case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "RIL_REQUEST_SET_INITIAL_ATTACH_APN";
5208 case RIL_REQUEST_IMS_REGISTRATION_STATE: return "IMS_REGISTRATION_STATE";
5209 case RIL_REQUEST_IMS_SEND_SMS: return "IMS_SEND_SMS";
Howard Sue32dbfd2015-01-07 15:55:57 +08005210 case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC: return "SIM_TRANSMIT_APDU_BASIC";
5211 case RIL_REQUEST_SIM_OPEN_CHANNEL: return "SIM_OPEN_CHANNEL";
5212 case RIL_REQUEST_SIM_CLOSE_CHANNEL: return "SIM_CLOSE_CHANNEL";
5213 case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL: return "SIM_TRANSMIT_APDU_CHANNEL";
Howard Subd82ef12015-04-12 10:25:05 +02005214 case RIL_REQUEST_GET_RADIO_CAPABILITY: return "RIL_REQUEST_GET_RADIO_CAPABILITY";
5215 case RIL_REQUEST_SET_RADIO_CAPABILITY: return "RIL_REQUEST_SET_RADIO_CAPABILITY";
Howard Sue32dbfd2015-01-07 15:55:57 +08005216 case RIL_REQUEST_SET_UICC_SUBSCRIPTION: return "SET_UICC_SUBSCRIPTION";
5217 case RIL_REQUEST_ALLOW_DATA: return "ALLOW_DATA";
5218 case RIL_REQUEST_GET_HARDWARE_CONFIG: return "GET_HARDWARE_CONFIG";
5219 case RIL_REQUEST_SIM_AUTHENTICATION: return "SIM_AUTHENTICATION";
5220 case RIL_REQUEST_GET_DC_RT_INFO: return "GET_DC_RT_INFO";
5221 case RIL_REQUEST_SET_DC_RT_INFO_RATE: return "SET_DC_RT_INFO_RATE";
5222 case RIL_REQUEST_SET_DATA_PROFILE: return "SET_DATA_PROFILE";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005223 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
5224 case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
5225 case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
5226 case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
5227 case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
5228 case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
5229 case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
5230 case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
5231 case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
5232 case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
Howard Subd82ef12015-04-12 10:25:05 +02005233 case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
5234 case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005235 case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
5236 case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
5237 case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
5238 case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
5239 case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FUL";
5240 case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005241 case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
5242 case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
5243 case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_NEW_CDMA_SMS";
5244 case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_NEW_BROADCAST_SMS";
5245 case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
5246 case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
5247 case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
5248 case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
5249 case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
5250 case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
5251 case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
5252 case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONE";
5253 case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
5254 case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED";
5255 case RIL_UNSOL_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
5256 case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
5257 case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
5258 case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED";
Ethan Chend6e30652013-08-04 22:49:56 -07005259 case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST";
Andrew Jiangca4a9a02014-01-18 18:04:08 -05005260 case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return "RESPONSE_IMS_NETWORK_STATE_CHANGED";
Howard Sue32dbfd2015-01-07 15:55:57 +08005261 case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED: return "UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED";
5262 case RIL_UNSOL_SRVCC_STATE_NOTIFY: return "UNSOL_SRVCC_STATE_NOTIFY";
5263 case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: return "HARDWARE_CONFIG_CHANGED";
5264 case RIL_UNSOL_DC_RT_INFO_CHANGED: return "UNSOL_DC_RT_INFO_CHANGED";
Howard Subd82ef12015-04-12 10:25:05 +02005265 case RIL_UNSOL_RADIO_CAPABILITY: return "UNSOL_RADIO_CAPABILITY";
5266 case RIL_UNSOL_ON_SS: return "UNSOL_ON_SS";
5267 case RIL_UNSOL_STK_CC_ALPHA_NOTIFY: return "UNSOL_STK_CC_ALPHA_NOTIFY";
Howard Sue32dbfd2015-01-07 15:55:57 +08005268 case RIL_REQUEST_SHUTDOWN: return "SHUTDOWN";
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005269 default: return "<unknown request>";
5270 }
5271}
5272
Howard Sue32dbfd2015-01-07 15:55:57 +08005273const char *
5274rilSocketIdToString(RIL_SOCKET_ID socket_id)
5275{
5276 switch(socket_id) {
5277 case RIL_SOCKET_1:
5278 return "RIL_SOCKET_1";
5279#if (SIM_COUNT >= 2)
5280 case RIL_SOCKET_2:
5281 return "RIL_SOCKET_2";
5282#endif
5283#if (SIM_COUNT >= 3)
5284 case RIL_SOCKET_3:
5285 return "RIL_SOCKET_3";
5286#endif
5287#if (SIM_COUNT >= 4)
5288 case RIL_SOCKET_4:
5289 return "RIL_SOCKET_4";
5290#endif
5291 default:
5292 return "not a valid RIL";
5293 }
5294}
5295
Daniel Hillenbrand601dc852013-07-07 10:06:59 +02005296} /* namespace android */
Dheeraj Shettycc231012014-07-02 21:27:57 +02005297
5298void rilEventAddWakeup_helper(struct ril_event *ev) {
5299 android::rilEventAddWakeup(ev);
5300}
5301
5302void listenCallback_helper(int fd, short flags, void *param) {
5303 android::listenCallback(fd, flags, param);
5304}
5305
5306int blockingWrite_helper(int fd, void *buffer, size_t len) {
5307 return android::blockingWrite(fd, buffer, len);
5308}