ril_service.cpp revision 65d3486b2fd5dcff52dae8697ec471ab1ad577b8
1/*
2 * Copyright (c) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "RILC"
18
19#include <android/hardware/radio/1.0/IRadio.h>
20#include <android/hardware/radio/deprecated/1.0/IOemHook.h>
21
22#include <hwbinder/IPCThreadState.h>
23#include <hwbinder/ProcessState.h>
24#include <ril_service.h>
25#include <hidl/HidlTransportSupport.h>
26#include <utils/SystemClock.h>
27#include <inttypes.h>
28
29#define INVALID_HEX_CHAR 16
30
31// Enable verbose logging
32#define VDBG 0
33
34using namespace android::hardware::radio::V1_0;
35using namespace android::hardware::radio::deprecated::V1_0;
36using ::android::hardware::configureRpcThreadpool;
37using ::android::hardware::joinRpcThreadpool;
38using ::android::hardware::Return;
39using ::android::hardware::hidl_string;
40using ::android::hardware::hidl_vec;
41using ::android::hardware::hidl_array;
42using ::android::hardware::Void;
43using android::CommandInfo;
44using android::RequestInfo;
45using android::requestToString;
46using android::sp;
47
48#define BOOL_TO_INT(x) (x ? 1 : 0)
49#define ATOI_NULL_HANDLED(x) (x ? atoi(x) : -1)
50#define ATOI_NULL_HANDLED_DEF(x, defaultVal) (x ? atoi(x) : defaultVal)
51
52#if defined(ANDROID_MULTI_SIM)
53#define CALL_ONREQUEST(a, b, c, d, e) \
54        s_vendorFunctions->onRequest((a), (b), (c), (d), ((RIL_SOCKET_ID)(e)))
55#define CALL_ONSTATEREQUEST(a) s_vendorFunctions->onStateRequest((RIL_SOCKET_ID)(a))
56#else
57#define CALL_ONREQUEST(a, b, c, d, e) s_vendorFunctions->onRequest((a), (b), (c), (d))
58#define CALL_ONSTATEREQUEST(a) s_vendorFunctions->onStateRequest()
59#endif
60
61RIL_RadioFunctions *s_vendorFunctions = NULL;
62static CommandInfo *s_commands;
63
64struct RadioImpl;
65struct OemHookImpl;
66
67#if (SIM_COUNT >= 2)
68sp<RadioImpl> radioService[SIM_COUNT];
69sp<OemHookImpl> oemHookService[SIM_COUNT];
70// counter used for synchronization. It is incremented every time response callbacks are updated.
71volatile int32_t mCounterRadio[SIM_COUNT];
72volatile int32_t mCounterOemHook[SIM_COUNT];
73#else
74sp<RadioImpl> radioService[1];
75sp<OemHookImpl> oemHookService[1];
76// counter used for synchronization. It is incremented every time response callbacks are updated.
77volatile int32_t mCounterRadio[1];
78volatile int32_t mCounterOemHook[1];
79#endif
80
81static pthread_rwlock_t radioServiceRwlock = PTHREAD_RWLOCK_INITIALIZER;
82
83#if (SIM_COUNT >= 2)
84static pthread_rwlock_t radioServiceRwlock2 = PTHREAD_RWLOCK_INITIALIZER;
85#if (SIM_COUNT >= 3)
86static pthread_rwlock_t radioServiceRwlock3 = PTHREAD_RWLOCK_INITIALIZER;
87#if (SIM_COUNT >= 4)
88static pthread_rwlock_t radioServiceRwlock4 = PTHREAD_RWLOCK_INITIALIZER;
89#endif
90#endif
91#endif
92
93void convertRilHardwareConfigListToHal(void *response, size_t responseLen,
94        hidl_vec<HardwareConfig>& records);
95
96void convertRilRadioCapabilityToHal(void *response, size_t responseLen, RadioCapability& rc);
97
98void convertRilLceDataInfoToHal(void *response, size_t responseLen, LceDataInfo& lce);
99
100void convertRilSignalStrengthToHal(void *response, size_t responseLen,
101        SignalStrength& signalStrength);
102
103void convertRilDataCallToHal(RIL_Data_Call_Response_v11 *dcResponse,
104        SetupDataCallResult& dcResult);
105
106void convertRilDataCallListToHal(void *response, size_t responseLen,
107        hidl_vec<SetupDataCallResult>& dcResultList);
108
109void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec<CellInfo>& records);
110
111struct RadioImpl : public IRadio {
112    int32_t mSlotId;
113    sp<IRadioResponse> mRadioResponse;
114    sp<IRadioIndication> mRadioIndication;
115
116    Return<void> setResponseFunctions(
117            const ::android::sp<IRadioResponse>& radioResponse,
118            const ::android::sp<IRadioIndication>& radioIndication);
119
120    Return<void> getIccCardStatus(int32_t serial);
121
122    Return<void> supplyIccPinForApp(int32_t serial, const hidl_string& pin,
123            const hidl_string& aid);
124
125    Return<void> supplyIccPukForApp(int32_t serial, const hidl_string& puk,
126            const hidl_string& pin, const hidl_string& aid);
127
128    Return<void> supplyIccPin2ForApp(int32_t serial,
129            const hidl_string& pin2,
130            const hidl_string& aid);
131
132    Return<void> supplyIccPuk2ForApp(int32_t serial, const hidl_string& puk2,
133            const hidl_string& pin2, const hidl_string& aid);
134
135    Return<void> changeIccPinForApp(int32_t serial, const hidl_string& oldPin,
136            const hidl_string& newPin, const hidl_string& aid);
137
138    Return<void> changeIccPin2ForApp(int32_t serial, const hidl_string& oldPin2,
139            const hidl_string& newPin2, const hidl_string& aid);
140
141    Return<void> supplyNetworkDepersonalization(int32_t serial, const hidl_string& netPin);
142
143    Return<void> getCurrentCalls(int32_t serial);
144
145    Return<void> dial(int32_t serial, const Dial& dialInfo);
146
147    Return<void> getImsiForApp(int32_t serial,
148            const ::android::hardware::hidl_string& aid);
149
150    Return<void> hangup(int32_t serial, int32_t gsmIndex);
151
152    Return<void> hangupWaitingOrBackground(int32_t serial);
153
154    Return<void> hangupForegroundResumeBackground(int32_t serial);
155
156    Return<void> switchWaitingOrHoldingAndActive(int32_t serial);
157
158    Return<void> conference(int32_t serial);
159
160    Return<void> rejectCall(int32_t serial);
161
162    Return<void> getLastCallFailCause(int32_t serial);
163
164    Return<void> getSignalStrength(int32_t serial);
165
166    Return<void> getVoiceRegistrationState(int32_t serial);
167
168    Return<void> getDataRegistrationState(int32_t serial);
169
170    Return<void> getOperator(int32_t serial);
171
172    Return<void> setRadioPower(int32_t serial, bool on);
173
174    Return<void> sendDtmf(int32_t serial,
175            const ::android::hardware::hidl_string& s);
176
177    Return<void> sendSms(int32_t serial, const GsmSmsMessage& message);
178
179    Return<void> sendSMSExpectMore(int32_t serial, const GsmSmsMessage& message);
180
181    Return<void> setupDataCall(int32_t serial,
182            RadioTechnology radioTechnology,
183            const DataProfileInfo& profileInfo,
184            bool modemCognitive,
185            bool roamingAllowed,
186            bool isRoaming);
187
188    Return<void> iccIOForApp(int32_t serial,
189            const IccIo& iccIo);
190
191    Return<void> sendUssd(int32_t serial,
192            const ::android::hardware::hidl_string& ussd);
193
194    Return<void> cancelPendingUssd(int32_t serial);
195
196    Return<void> getClir(int32_t serial);
197
198    Return<void> setClir(int32_t serial, int32_t status);
199
200    Return<void> getCallForwardStatus(int32_t serial,
201            const CallForwardInfo& callInfo);
202
203    Return<void> setCallForward(int32_t serial,
204            const CallForwardInfo& callInfo);
205
206    Return<void> getCallWaiting(int32_t serial, int32_t serviceClass);
207
208    Return<void> setCallWaiting(int32_t serial, bool enable, int32_t serviceClass);
209
210    Return<void> acknowledgeLastIncomingGsmSms(int32_t serial,
211            bool success, SmsAcknowledgeFailCause cause);
212
213    Return<void> acceptCall(int32_t serial);
214
215    Return<void> deactivateDataCall(int32_t serial,
216            int32_t cid, bool reasonRadioShutDown);
217
218    Return<void> getFacilityLockForApp(int32_t serial,
219            const ::android::hardware::hidl_string& facility,
220            const ::android::hardware::hidl_string& password,
221            int32_t serviceClass,
222            const ::android::hardware::hidl_string& appId);
223
224    Return<void> setFacilityLockForApp(int32_t serial,
225            const ::android::hardware::hidl_string& facility,
226            bool lockState,
227            const ::android::hardware::hidl_string& password,
228            int32_t serviceClass,
229            const ::android::hardware::hidl_string& appId);
230
231    Return<void> setBarringPassword(int32_t serial,
232            const ::android::hardware::hidl_string& facility,
233            const ::android::hardware::hidl_string& oldPassword,
234            const ::android::hardware::hidl_string& newPassword);
235
236    Return<void> getNetworkSelectionMode(int32_t serial);
237
238    Return<void> setNetworkSelectionModeAutomatic(int32_t serial);
239
240    Return<void> setNetworkSelectionModeManual(int32_t serial,
241            const ::android::hardware::hidl_string& operatorNumeric);
242
243    Return<void> getAvailableNetworks(int32_t serial);
244
245    Return<void> startDtmf(int32_t serial,
246            const ::android::hardware::hidl_string& s);
247
248    Return<void> stopDtmf(int32_t serial);
249
250    Return<void> getBasebandVersion(int32_t serial);
251
252    Return<void> separateConnection(int32_t serial, int32_t gsmIndex);
253
254    Return<void> setMute(int32_t serial, bool enable);
255
256    Return<void> getMute(int32_t serial);
257
258    Return<void> getClip(int32_t serial);
259
260    Return<void> getDataCallList(int32_t serial);
261
262    Return<void> setSuppServiceNotifications(int32_t serial, bool enable);
263
264    Return<void> writeSmsToSim(int32_t serial,
265            const SmsWriteArgs& smsWriteArgs);
266
267    Return<void> deleteSmsOnSim(int32_t serial, int32_t index);
268
269    Return<void> setBandMode(int32_t serial, RadioBandMode mode);
270
271    Return<void> getAvailableBandModes(int32_t serial);
272
273    Return<void> sendEnvelope(int32_t serial,
274            const ::android::hardware::hidl_string& command);
275
276    Return<void> sendTerminalResponseToSim(int32_t serial,
277            const ::android::hardware::hidl_string& commandResponse);
278
279    Return<void> handleStkCallSetupRequestFromSim(int32_t serial, bool accept);
280
281    Return<void> explicitCallTransfer(int32_t serial);
282
283    Return<void> setPreferredNetworkType(int32_t serial, PreferredNetworkType nwType);
284
285    Return<void> getPreferredNetworkType(int32_t serial);
286
287    Return<void> getNeighboringCids(int32_t serial);
288
289    Return<void> setLocationUpdates(int32_t serial, bool enable);
290
291    Return<void> setCdmaSubscriptionSource(int32_t serial,
292            CdmaSubscriptionSource cdmaSub);
293
294    Return<void> setCdmaRoamingPreference(int32_t serial, CdmaRoamingType type);
295
296    Return<void> getCdmaRoamingPreference(int32_t serial);
297
298    Return<void> setTTYMode(int32_t serial, TtyMode mode);
299
300    Return<void> getTTYMode(int32_t serial);
301
302    Return<void> setPreferredVoicePrivacy(int32_t serial, bool enable);
303
304    Return<void> getPreferredVoicePrivacy(int32_t serial);
305
306    Return<void> sendCDMAFeatureCode(int32_t serial,
307            const ::android::hardware::hidl_string& featureCode);
308
309    Return<void> sendBurstDtmf(int32_t serial,
310            const ::android::hardware::hidl_string& dtmf,
311            int32_t on,
312            int32_t off);
313
314    Return<void> sendCdmaSms(int32_t serial, const CdmaSmsMessage& sms);
315
316    Return<void> acknowledgeLastIncomingCdmaSms(int32_t serial,
317            const CdmaSmsAck& smsAck);
318
319    Return<void> getGsmBroadcastConfig(int32_t serial);
320
321    Return<void> setGsmBroadcastConfig(int32_t serial,
322            const hidl_vec<GsmBroadcastSmsConfigInfo>& configInfo);
323
324    Return<void> setGsmBroadcastActivation(int32_t serial, bool activate);
325
326    Return<void> getCdmaBroadcastConfig(int32_t serial);
327
328    Return<void> setCdmaBroadcastConfig(int32_t serial,
329            const hidl_vec<CdmaBroadcastSmsConfigInfo>& configInfo);
330
331    Return<void> setCdmaBroadcastActivation(int32_t serial, bool activate);
332
333    Return<void> getCDMASubscription(int32_t serial);
334
335    Return<void> writeSmsToRuim(int32_t serial, const CdmaSmsWriteArgs& cdmaSms);
336
337    Return<void> deleteSmsOnRuim(int32_t serial, int32_t index);
338
339    Return<void> getDeviceIdentity(int32_t serial);
340
341    Return<void> exitEmergencyCallbackMode(int32_t serial);
342
343    Return<void> getSmscAddress(int32_t serial);
344
345    Return<void> setSmscAddress(int32_t serial,
346            const ::android::hardware::hidl_string& smsc);
347
348    Return<void> reportSmsMemoryStatus(int32_t serial, bool available);
349
350    Return<void> reportStkServiceIsRunning(int32_t serial);
351
352    Return<void> getCdmaSubscriptionSource(int32_t serial);
353
354    Return<void> requestIsimAuthentication(int32_t serial,
355            const ::android::hardware::hidl_string& challenge);
356
357    Return<void> acknowledgeIncomingGsmSmsWithPdu(int32_t serial,
358            bool success,
359            const ::android::hardware::hidl_string& ackPdu);
360
361    Return<void> sendEnvelopeWithStatus(int32_t serial,
362            const ::android::hardware::hidl_string& contents);
363
364    Return<void> getVoiceRadioTechnology(int32_t serial);
365
366    Return<void> getCellInfoList(int32_t serial);
367
368    Return<void> setCellInfoListRate(int32_t serial, int32_t rate);
369
370    Return<void> setInitialAttachApn(int32_t serial, const DataProfileInfo& dataProfileInfo,
371            bool modemCognitive, bool isRoaming);
372
373    Return<void> getImsRegistrationState(int32_t serial);
374
375    Return<void> sendImsSms(int32_t serial, const ImsSmsMessage& message);
376
377    Return<void> iccTransmitApduBasicChannel(int32_t serial, const SimApdu& message);
378
379    Return<void> iccOpenLogicalChannel(int32_t serial,
380            const ::android::hardware::hidl_string& aid, int32_t p2);
381
382    Return<void> iccCloseLogicalChannel(int32_t serial, int32_t channelId);
383
384    Return<void> iccTransmitApduLogicalChannel(int32_t serial, const SimApdu& message);
385
386    Return<void> nvReadItem(int32_t serial, NvItem itemId);
387
388    Return<void> nvWriteItem(int32_t serial, const NvWriteItem& item);
389
390    Return<void> nvWriteCdmaPrl(int32_t serial,
391            const ::android::hardware::hidl_vec<uint8_t>& prl);
392
393    Return<void> nvResetConfig(int32_t serial, ResetNvType resetType);
394
395    Return<void> setUiccSubscription(int32_t serial, const SelectUiccSub& uiccSub);
396
397    Return<void> setDataAllowed(int32_t serial, bool allow);
398
399    Return<void> getHardwareConfig(int32_t serial);
400
401    Return<void> requestIccSimAuthentication(int32_t serial,
402            int32_t authContext,
403            const ::android::hardware::hidl_string& authData,
404            const ::android::hardware::hidl_string& aid);
405
406    Return<void> setDataProfile(int32_t serial,
407            const ::android::hardware::hidl_vec<DataProfileInfo>& profiles, bool isRoaming);
408
409    Return<void> requestShutdown(int32_t serial);
410
411    Return<void> getRadioCapability(int32_t serial);
412
413    Return<void> setRadioCapability(int32_t serial, const RadioCapability& rc);
414
415    Return<void> startLceService(int32_t serial, int32_t reportInterval, bool pullMode);
416
417    Return<void> stopLceService(int32_t serial);
418
419    Return<void> pullLceData(int32_t serial);
420
421    Return<void> getModemActivityInfo(int32_t serial);
422
423    Return<void> setAllowedCarriers(int32_t serial,
424            bool allAllowed,
425            const CarrierRestrictions& carriers);
426
427    Return<void> getAllowedCarriers(int32_t serial);
428
429    Return<void> sendDeviceState(int32_t serial, DeviceStateType deviceStateType, bool state);
430
431    Return<void> setIndicationFilter(int32_t serial, int32_t indicationFilter);
432
433    Return<void> setSimCardPower(int32_t serial, bool powerUp);
434
435    Return<void> responseAcknowledgement();
436
437    void checkReturnStatus(Return<void>& ret);
438};
439
440struct OemHookImpl : public IOemHook {
441    int32_t mSlotId;
442    sp<IOemHookResponse> mOemHookResponse;
443    sp<IOemHookIndication> mOemHookIndication;
444
445    Return<void> setResponseFunctions(
446            const ::android::sp<IOemHookResponse>& oemHookResponse,
447            const ::android::sp<IOemHookIndication>& oemHookIndication);
448
449    Return<void> sendRequestRaw(int32_t serial,
450            const ::android::hardware::hidl_vec<uint8_t>& data);
451
452    Return<void> sendRequestStrings(int32_t serial,
453            const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& data);
454};
455
456void memsetAndFreeStrings(int numPointers, ...) {
457    va_list ap;
458    va_start(ap, numPointers);
459    for (int i = 0; i < numPointers; i++) {
460        char *ptr = va_arg(ap, char *);
461        if (ptr) {
462#ifdef MEMSET_FREED
463            // TODO: Should pass in the maximum length of the string
464            memsetString(ptr);
465#endif
466            free(ptr);
467        }
468    }
469    va_end(ap);
470}
471
472void sendErrorResponse(RequestInfo *pRI, RIL_Errno err) {
473    pRI->pCI->responseFunction((int) pRI->socket_id,
474            (int) RadioResponseType::SOLICITED, pRI->token, err, NULL, 0);
475}
476
477/**
478 * Copies over src to dest. If memory allocation fails, responseFunction() is called for the
479 * request with error RIL_E_NO_MEMORY.
480 * Returns true on success, and false on failure.
481 */
482bool copyHidlStringToRil(char **dest, const hidl_string &src, RequestInfo *pRI) {
483    size_t len = src.size();
484    if (len == 0) {
485        *dest = NULL;
486        return true;
487    }
488    *dest = (char *) calloc(len + 1, sizeof(char));
489    if (*dest == NULL) {
490        RLOGE("Memory allocation failed for request %s", requestToString(pRI->pCI->requestNumber));
491        sendErrorResponse(pRI, RIL_E_NO_MEMORY);
492        return false;
493    }
494    strncpy(*dest, src.c_str(), len + 1);
495    return true;
496}
497
498hidl_string convertCharPtrToHidlString(const char *ptr) {
499    hidl_string ret;
500    if (ptr != NULL) {
501        // TODO: replace this with strnlen
502        ret.setToExternal(ptr, strlen(ptr));
503    }
504    return ret;
505}
506
507bool dispatchVoid(int serial, int slotId, int request) {
508    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
509    if (pRI == NULL) {
510        return false;
511    }
512    CALL_ONREQUEST(request, NULL, 0, pRI, slotId);
513    return true;
514}
515
516bool dispatchString(int serial, int slotId, int request, const char * str) {
517    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
518    if (pRI == NULL) {
519        return false;
520    }
521
522    char *pString;
523    if (!copyHidlStringToRil(&pString, str, pRI)) {
524        return false;
525    }
526
527    CALL_ONREQUEST(request, pString, sizeof(char *), pRI, slotId);
528
529    memsetAndFreeStrings(1, pString);
530    return true;
531}
532
533bool dispatchStrings(int serial, int slotId, int request, int countStrings, ...) {
534    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
535    if (pRI == NULL) {
536        return false;
537    }
538
539    char **pStrings;
540    pStrings = (char **)calloc(countStrings, sizeof(char *));
541    if (pStrings == NULL) {
542        RLOGE("Memory allocation failed for request %s", requestToString(request));
543        sendErrorResponse(pRI, RIL_E_NO_MEMORY);
544        return false;
545    }
546    va_list ap;
547    va_start(ap, countStrings);
548    for (int i = 0; i < countStrings; i++) {
549        const char* str = va_arg(ap, const char *);
550        if (!copyHidlStringToRil(&pStrings[i], hidl_string(str), pRI)) {
551            va_end(ap);
552            for (int j = 0; j < i; j++) {
553                memsetAndFreeStrings(1, pStrings[j]);
554            }
555            free(pStrings);
556            return false;
557        }
558    }
559    va_end(ap);
560
561    CALL_ONREQUEST(request, pStrings, countStrings * sizeof(char *), pRI, slotId);
562
563    if (pStrings != NULL) {
564        for (int i = 0 ; i < countStrings ; i++) {
565            memsetAndFreeStrings(1, pStrings[i]);
566        }
567
568#ifdef MEMSET_FREED
569        memset(pStrings, 0, countStrings * sizeof(char *));
570#endif
571        free(pStrings);
572    }
573    return true;
574}
575
576bool dispatchStrings(int serial, int slotId, int request, const hidl_vec<hidl_string>& data) {
577    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
578    if (pRI == NULL) {
579        return false;
580    }
581
582    int countStrings = data.size();
583    char **pStrings;
584    pStrings = (char **)calloc(countStrings, sizeof(char *));
585    if (pStrings == NULL) {
586        RLOGE("Memory allocation failed for request %s", requestToString(request));
587        sendErrorResponse(pRI, RIL_E_NO_MEMORY);
588        return false;
589    }
590
591    for (int i = 0; i < countStrings; i++) {
592        if (!copyHidlStringToRil(&pStrings[i], data[i], pRI)) {
593            for (int j = 0; j < i; j++) {
594                memsetAndFreeStrings(1, pStrings[j]);
595            }
596            free(pStrings);
597            return false;
598        }
599    }
600
601    CALL_ONREQUEST(request, pStrings, countStrings * sizeof(char *), pRI, slotId);
602
603    if (pStrings != NULL) {
604        for (int i = 0 ; i < countStrings ; i++) {
605            memsetAndFreeStrings(1, pStrings[i]);
606        }
607
608#ifdef MEMSET_FREED
609        memset(pStrings, 0, countStrings * sizeof(char *));
610#endif
611        free(pStrings);
612    }
613    return true;
614}
615
616bool dispatchInts(int serial, int slotId, int request, int countInts, ...) {
617    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
618    if (pRI == NULL) {
619        return false;
620    }
621
622    int *pInts = (int *)calloc(countInts, sizeof(int));
623
624    if (pInts == NULL) {
625        RLOGE("Memory allocation failed for request %s", requestToString(request));
626        sendErrorResponse(pRI, RIL_E_NO_MEMORY);
627        return false;
628    }
629    va_list ap;
630    va_start(ap, countInts);
631    for (int i = 0; i < countInts; i++) {
632        pInts[i] = va_arg(ap, int);
633    }
634    va_end(ap);
635
636    CALL_ONREQUEST(request, pInts, countInts * sizeof(int), pRI, slotId);
637
638    if (pInts != NULL) {
639#ifdef MEMSET_FREED
640        memset(pInts, 0, countInts * sizeof(int));
641#endif
642        free(pInts);
643    }
644    return true;
645}
646
647bool dispatchCallForwardStatus(int serial, int slotId, int request,
648                              const CallForwardInfo& callInfo) {
649    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
650    if (pRI == NULL) {
651        return false;
652    }
653
654    RIL_CallForwardInfo cf;
655    cf.status = (int) callInfo.status;
656    cf.reason = callInfo.reason;
657    cf.serviceClass = callInfo.serviceClass;
658    cf.toa = callInfo.toa;
659    cf.timeSeconds = callInfo.timeSeconds;
660
661    if (!copyHidlStringToRil(&cf.number, callInfo.number, pRI)) {
662        return false;
663    }
664
665    CALL_ONREQUEST(request, &cf, sizeof(cf), pRI, slotId);
666
667    memsetAndFreeStrings(1, cf.number);
668
669    return true;
670}
671
672bool dispatchRaw(int serial, int slotId, int request, const hidl_vec<uint8_t>& rawBytes) {
673    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
674    if (pRI == NULL) {
675        return false;
676    }
677
678    const uint8_t *uData = rawBytes.data();
679
680    CALL_ONREQUEST(request, (void *) uData, rawBytes.size(), pRI, slotId);
681
682    return true;
683}
684
685bool dispatchIccApdu(int serial, int slotId, int request, const SimApdu& message) {
686    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
687    if (pRI == NULL) {
688        return false;
689    }
690
691    RIL_SIM_APDU apdu = {};
692
693    apdu.sessionid = message.sessionId;
694    apdu.cla = message.cla;
695    apdu.instruction = message.instruction;
696    apdu.p1 = message.p1;
697    apdu.p2 = message.p2;
698    apdu.p3 = message.p3;
699
700    if (!copyHidlStringToRil(&apdu.data, message.data, pRI)) {
701        return false;
702    }
703
704    CALL_ONREQUEST(request, &apdu, sizeof(apdu), pRI, slotId);
705
706    memsetAndFreeStrings(1, apdu.data);
707
708    return true;
709}
710
711void checkReturnStatus(int32_t slotId, Return<void>& ret, bool isRadioService) {
712    if (ret.isOk() == false) {
713        RLOGE("checkReturnStatus: unable to call response/indication callback");
714        // Remote process hosting the callbacks must be dead. Reset the callback objects;
715        // there's no other recovery to be done here. When the client process is back up, it will
716        // call setResponseFunctions()
717
718        // Caller should already hold rdlock, release that first
719        // note the current counter to avoid overwriting updates made by another thread before
720        // write lock is acquired.
721        int counter = isRadioService ? mCounterRadio[slotId] : mCounterOemHook[slotId];
722        pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock(slotId);
723        int ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
724        assert(ret == 0);
725
726        // acquire wrlock
727        ret = pthread_rwlock_wrlock(radioServiceRwlockPtr);
728        assert(ret == 0);
729
730        // make sure the counter value has not changed
731        if (counter == (isRadioService ? mCounterRadio[slotId] : mCounterOemHook[slotId])) {
732            if (isRadioService) {
733                radioService[slotId]->mRadioResponse = NULL;
734                radioService[slotId]->mRadioIndication = NULL;
735            } else {
736                oemHookService[slotId]->mOemHookResponse = NULL;
737                oemHookService[slotId]->mOemHookIndication = NULL;
738            }
739            isRadioService ? mCounterRadio[slotId]++ : mCounterOemHook[slotId]++;
740        } else {
741            RLOGE("checkReturnStatus: not resetting responseFunctions as they likely "
742                    "got updated on another thread");
743        }
744
745        // release wrlock
746        ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
747        assert(ret == 0);
748
749        // Reacquire rdlock
750        ret = pthread_rwlock_rdlock(radioServiceRwlockPtr);
751        assert(ret == 0);
752    }
753}
754
755void RadioImpl::checkReturnStatus(Return<void>& ret) {
756    ::checkReturnStatus(mSlotId, ret, true);
757}
758
759Return<void> RadioImpl::setResponseFunctions(
760        const ::android::sp<IRadioResponse>& radioResponseParam,
761        const ::android::sp<IRadioIndication>& radioIndicationParam) {
762    RLOGD("setResponseFunctions");
763
764    pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock(mSlotId);
765    int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr);
766    assert(ret == 0);
767
768    mRadioResponse = radioResponseParam;
769    mRadioIndication = radioIndicationParam;
770    mCounterRadio[mSlotId]++;
771
772    ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
773    assert(ret == 0);
774
775    // client is connected. Send initial indications.
776    android::onNewCommandConnect((RIL_SOCKET_ID) mSlotId);
777
778    return Void();
779}
780
781Return<void> RadioImpl::getIccCardStatus(int32_t serial) {
782#if VDBG
783    RLOGD("getIccCardStatus: serial %d", serial);
784#endif
785    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_SIM_STATUS);
786    return Void();
787}
788
789Return<void> RadioImpl::supplyIccPinForApp(int32_t serial, const hidl_string& pin,
790        const hidl_string& aid) {
791#if VDBG
792    RLOGD("supplyIccPinForApp: serial %d", serial);
793#endif
794    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PIN,
795            2, pin.c_str(), aid.c_str());
796    return Void();
797}
798
799Return<void> RadioImpl::supplyIccPukForApp(int32_t serial, const hidl_string& puk,
800                                           const hidl_string& pin, const hidl_string& aid) {
801#if VDBG
802    RLOGD("supplyIccPukForApp: serial %d", serial);
803#endif
804    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PUK,
805            3, puk.c_str(), pin.c_str(), aid.c_str());
806    return Void();
807}
808
809Return<void> RadioImpl::supplyIccPin2ForApp(int32_t serial, const hidl_string& pin2,
810                                            const hidl_string& aid) {
811#if VDBG
812    RLOGD("supplyIccPin2ForApp: serial %d", serial);
813#endif
814    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PIN2,
815            2, pin2.c_str(), aid.c_str());
816    return Void();
817}
818
819Return<void> RadioImpl::supplyIccPuk2ForApp(int32_t serial, const hidl_string& puk2,
820                                            const hidl_string& pin2, const hidl_string& aid) {
821#if VDBG
822    RLOGD("supplyIccPuk2ForApp: serial %d", serial);
823#endif
824    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PUK2,
825            3, puk2.c_str(), pin2.c_str(), aid.c_str());
826    return Void();
827}
828
829Return<void> RadioImpl::changeIccPinForApp(int32_t serial, const hidl_string& oldPin,
830                                           const hidl_string& newPin, const hidl_string& aid) {
831#if VDBG
832    RLOGD("changeIccPinForApp: serial %d", serial);
833#endif
834    dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_SIM_PIN,
835            3, oldPin.c_str(), newPin.c_str(), aid.c_str());
836    return Void();
837}
838
839Return<void> RadioImpl::changeIccPin2ForApp(int32_t serial, const hidl_string& oldPin2,
840                                            const hidl_string& newPin2, const hidl_string& aid) {
841#if VDBG
842    RLOGD("changeIccPin2ForApp: serial %d", serial);
843#endif
844    dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_SIM_PIN2,
845            3, oldPin2.c_str(), newPin2.c_str(), aid.c_str());
846    return Void();
847}
848
849Return<void> RadioImpl::supplyNetworkDepersonalization(int32_t serial,
850                                                       const hidl_string& netPin) {
851#if VDBG
852    RLOGD("supplyNetworkDepersonalization: serial %d", serial);
853#endif
854    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION,
855            1, netPin.c_str());
856    return Void();
857}
858
859Return<void> RadioImpl::getCurrentCalls(int32_t serial) {
860#if VDBG
861    RLOGD("getCurrentCalls: serial %d", serial);
862#endif
863    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CURRENT_CALLS);
864    return Void();
865}
866
867Return<void> RadioImpl::dial(int32_t serial, const Dial& dialInfo) {
868#if VDBG
869    RLOGD("dial: serial %d", serial);
870#endif
871    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_DIAL);
872    if (pRI == NULL) {
873        return Void();
874    }
875    RIL_Dial dial = {};
876    RIL_UUS_Info uusInfo = {};
877    int32_t sizeOfDial = sizeof(dial);
878
879    if (!copyHidlStringToRil(&dial.address, dialInfo.address, pRI)) {
880        return Void();
881    }
882    dial.clir = (int) dialInfo.clir;
883
884    if (dialInfo.uusInfo.size() != 0) {
885        uusInfo.uusType = (RIL_UUS_Type) dialInfo.uusInfo[0].uusType;
886        uusInfo.uusDcs = (RIL_UUS_DCS) dialInfo.uusInfo[0].uusDcs;
887
888        if (dialInfo.uusInfo[0].uusData.size() == 0) {
889            uusInfo.uusData = NULL;
890            uusInfo.uusLength = 0;
891        } else {
892            if (!copyHidlStringToRil(&uusInfo.uusData, dialInfo.uusInfo[0].uusData, pRI)) {
893                memsetAndFreeStrings(1, dial.address);
894                return Void();
895            }
896            uusInfo.uusLength = dialInfo.uusInfo[0].uusData.size();
897        }
898
899        dial.uusInfo = &uusInfo;
900    }
901
902    CALL_ONREQUEST(RIL_REQUEST_DIAL, &dial, sizeOfDial, pRI, mSlotId);
903
904    memsetAndFreeStrings(2, dial.address, uusInfo.uusData);
905
906    return Void();
907}
908
909Return<void> RadioImpl::getImsiForApp(int32_t serial, const hidl_string& aid) {
910#if VDBG
911    RLOGD("getImsiForApp: serial %d", serial);
912#endif
913    dispatchStrings(serial, mSlotId, RIL_REQUEST_GET_IMSI,
914            1, aid.c_str());
915    return Void();
916}
917
918Return<void> RadioImpl::hangup(int32_t serial, int32_t gsmIndex) {
919#if VDBG
920    RLOGD("hangup: serial %d", serial);
921#endif
922    dispatchInts(serial, mSlotId, RIL_REQUEST_HANGUP, 1, gsmIndex);
923    return Void();
924}
925
926Return<void> RadioImpl::hangupWaitingOrBackground(int32_t serial) {
927#if VDBG
928    RLOGD("hangupWaitingOrBackground: serial %d", serial);
929#endif
930    dispatchVoid(serial, mSlotId, RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND);
931    return Void();
932}
933
934Return<void> RadioImpl::hangupForegroundResumeBackground(int32_t serial) {
935#if VDBG
936    RLOGD("hangupForegroundResumeBackground: serial %d", serial);
937#endif
938    dispatchVoid(serial, mSlotId, RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND);
939    return Void();
940}
941
942Return<void> RadioImpl::switchWaitingOrHoldingAndActive(int32_t serial) {
943#if VDBG
944    RLOGD("switchWaitingOrHoldingAndActive: serial %d", serial);
945#endif
946    dispatchVoid(serial, mSlotId, RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE);
947    return Void();
948}
949
950Return<void> RadioImpl::conference(int32_t serial) {
951#if VDBG
952    RLOGD("conference: serial %d", serial);
953#endif
954    dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFERENCE);
955    return Void();
956}
957
958Return<void> RadioImpl::rejectCall(int32_t serial) {
959#if VDBG
960    RLOGD("rejectCall: serial %d", serial);
961#endif
962    dispatchVoid(serial, mSlotId, RIL_REQUEST_UDUB);
963    return Void();
964}
965
966Return<void> RadioImpl::getLastCallFailCause(int32_t serial) {
967#if VDBG
968    RLOGD("getLastCallFailCause: serial %d", serial);
969#endif
970    dispatchVoid(serial, mSlotId, RIL_REQUEST_LAST_CALL_FAIL_CAUSE);
971    return Void();
972}
973
974Return<void> RadioImpl::getSignalStrength(int32_t serial) {
975#if VDBG
976    RLOGD("getSignalStrength: serial %d", serial);
977#endif
978    dispatchVoid(serial, mSlotId, RIL_REQUEST_SIGNAL_STRENGTH);
979    return Void();
980}
981
982Return<void> RadioImpl::getVoiceRegistrationState(int32_t serial) {
983#if VDBG
984    RLOGD("getVoiceRegistrationState: serial %d", serial);
985#endif
986    dispatchVoid(serial, mSlotId, RIL_REQUEST_VOICE_REGISTRATION_STATE);
987    return Void();
988}
989
990Return<void> RadioImpl::getDataRegistrationState(int32_t serial) {
991#if VDBG
992    RLOGD("getDataRegistrationState: serial %d", serial);
993#endif
994    dispatchVoid(serial, mSlotId, RIL_REQUEST_DATA_REGISTRATION_STATE);
995    return Void();
996}
997
998Return<void> RadioImpl::getOperator(int32_t serial) {
999#if VDBG
1000    RLOGD("getOperator: serial %d", serial);
1001#endif
1002    dispatchVoid(serial, mSlotId, RIL_REQUEST_OPERATOR);
1003    return Void();
1004}
1005
1006Return<void> RadioImpl::setRadioPower(int32_t serial, bool on) {
1007    RLOGD("setRadioPower: serial %d on %d", serial, on);
1008    dispatchInts(serial, mSlotId, RIL_REQUEST_RADIO_POWER, 1, BOOL_TO_INT(on));
1009    return Void();
1010}
1011
1012Return<void> RadioImpl::sendDtmf(int32_t serial, const hidl_string& s) {
1013#if VDBG
1014    RLOGD("sendDtmf: serial %d", serial);
1015#endif
1016    dispatchString(serial, mSlotId, RIL_REQUEST_DTMF, s.c_str());
1017    return Void();
1018}
1019
1020Return<void> RadioImpl::sendSms(int32_t serial, const GsmSmsMessage& message) {
1021#if VDBG
1022    RLOGD("sendSms: serial %d", serial);
1023#endif
1024    dispatchStrings(serial, mSlotId, RIL_REQUEST_SEND_SMS,
1025            2, message.smscPdu.c_str(), message.pdu.c_str());
1026    return Void();
1027}
1028
1029Return<void> RadioImpl::sendSMSExpectMore(int32_t serial, const GsmSmsMessage& message) {
1030#if VDBG
1031    RLOGD("sendSMSExpectMore: serial %d", serial);
1032#endif
1033    dispatchStrings(serial, mSlotId, RIL_REQUEST_SEND_SMS_EXPECT_MORE,
1034            2, message.smscPdu.c_str(), message.pdu.c_str());
1035    return Void();
1036}
1037
1038static bool convertMvnoTypeToString(MvnoType type, char *&str) {
1039    switch (type) {
1040        case MvnoType::IMSI:
1041            str = (char *)"imsi";
1042            return true;
1043        case MvnoType::GID:
1044            str = (char *)"gid";
1045            return true;
1046        case MvnoType::SPN:
1047            str = (char *)"spn";
1048            return true;
1049        case MvnoType::NONE:
1050            str = (char *)"";
1051            return true;
1052    }
1053    return false;
1054}
1055
1056Return<void> RadioImpl::setupDataCall(int32_t serial, RadioTechnology radioTechnology,
1057                                      const DataProfileInfo& dataProfileInfo, bool modemCognitive,
1058                                      bool roamingAllowed, bool isRoaming) {
1059
1060#if VDBG
1061    RLOGD("setupDataCall: serial %d", serial);
1062#endif
1063
1064    if (s_vendorFunctions->version >= 4 && s_vendorFunctions->version <= 14) {
1065        const hidl_string &protocol =
1066                (isRoaming ? dataProfileInfo.roamingProtocol : dataProfileInfo.protocol);
1067        dispatchStrings(serial, mSlotId, RIL_REQUEST_SETUP_DATA_CALL, 7,
1068            std::to_string((int) radioTechnology + 2).c_str(),
1069            std::to_string((int) dataProfileInfo.profileId).c_str(),
1070            dataProfileInfo.apn.c_str(),
1071            dataProfileInfo.user.c_str(),
1072            dataProfileInfo.password.c_str(),
1073            std::to_string((int) dataProfileInfo.authType).c_str(),
1074            protocol.c_str());
1075    } else if (s_vendorFunctions->version >= 15) {
1076        char *mvnoTypeStr = NULL;
1077        if (!convertMvnoTypeToString(dataProfileInfo.mvnoType, mvnoTypeStr)) {
1078            RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
1079                    RIL_REQUEST_SETUP_DATA_CALL);
1080            if (pRI != NULL) {
1081                sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
1082            }
1083            return Void();
1084        }
1085        dispatchStrings(serial, mSlotId, RIL_REQUEST_SETUP_DATA_CALL, 15,
1086            std::to_string((int) radioTechnology + 2).c_str(),
1087            std::to_string((int) dataProfileInfo.profileId).c_str(),
1088            dataProfileInfo.apn.c_str(),
1089            dataProfileInfo.user.c_str(),
1090            dataProfileInfo.password.c_str(),
1091            std::to_string((int) dataProfileInfo.authType).c_str(),
1092            dataProfileInfo.protocol.c_str(),
1093            dataProfileInfo.roamingProtocol.c_str(),
1094            std::to_string(dataProfileInfo.supportedApnTypesBitmap).c_str(),
1095            std::to_string(dataProfileInfo.bearerBitmap).c_str(),
1096            modemCognitive ? "1" : "0",
1097            std::to_string(dataProfileInfo.mtu).c_str(),
1098            mvnoTypeStr,
1099            dataProfileInfo.mvnoMatchData.c_str(),
1100            roamingAllowed ? "1" : "0");
1101    } else {
1102        RLOGE("Unsupported RIL version %d, min version expected 4", s_vendorFunctions->version);
1103        RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
1104                RIL_REQUEST_SETUP_DATA_CALL);
1105        if (pRI != NULL) {
1106            sendErrorResponse(pRI, RIL_E_REQUEST_NOT_SUPPORTED);
1107        }
1108    }
1109    return Void();
1110}
1111
1112Return<void> RadioImpl::iccIOForApp(int32_t serial, const IccIo& iccIo) {
1113#if VDBG
1114    RLOGD("iccIOForApp: serial %d", serial);
1115#endif
1116    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SIM_IO);
1117    if (pRI == NULL) {
1118        return Void();
1119    }
1120
1121    RIL_SIM_IO_v6 rilIccIo = {};
1122    rilIccIo.command = iccIo.command;
1123    rilIccIo.fileid = iccIo.fileId;
1124    if (!copyHidlStringToRil(&rilIccIo.path, iccIo.path, pRI)) {
1125        return Void();
1126    }
1127
1128    rilIccIo.p1 = iccIo.p1;
1129    rilIccIo.p2 = iccIo.p2;
1130    rilIccIo.p3 = iccIo.p3;
1131
1132    if (!copyHidlStringToRil(&rilIccIo.data, iccIo.data, pRI)) {
1133        memsetAndFreeStrings(1, rilIccIo.path);
1134        return Void();
1135    }
1136
1137    if (!copyHidlStringToRil(&rilIccIo.pin2, iccIo.pin2, pRI)) {
1138        memsetAndFreeStrings(2, rilIccIo.path, rilIccIo.data);
1139        return Void();
1140    }
1141
1142    if (!copyHidlStringToRil(&rilIccIo.aidPtr, iccIo.aid, pRI)) {
1143        memsetAndFreeStrings(3, rilIccIo.path, rilIccIo.data, rilIccIo.pin2);
1144        return Void();
1145    }
1146
1147    CALL_ONREQUEST(RIL_REQUEST_SIM_IO, &rilIccIo, sizeof(rilIccIo), pRI, mSlotId);
1148
1149    memsetAndFreeStrings(4, rilIccIo.path, rilIccIo.data, rilIccIo.pin2, rilIccIo.aidPtr);
1150
1151    return Void();
1152}
1153
1154Return<void> RadioImpl::sendUssd(int32_t serial, const hidl_string& ussd) {
1155#if VDBG
1156    RLOGD("sendUssd: serial %d", serial);
1157#endif
1158    dispatchString(serial, mSlotId, RIL_REQUEST_SEND_USSD, ussd.c_str());
1159    return Void();
1160}
1161
1162Return<void> RadioImpl::cancelPendingUssd(int32_t serial) {
1163#if VDBG
1164    RLOGD("cancelPendingUssd: serial %d", serial);
1165#endif
1166    dispatchVoid(serial, mSlotId, RIL_REQUEST_CANCEL_USSD);
1167    return Void();
1168}
1169
1170Return<void> RadioImpl::getClir(int32_t serial) {
1171#if VDBG
1172    RLOGD("getClir: serial %d", serial);
1173#endif
1174    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CLIR);
1175    return Void();
1176}
1177
1178Return<void> RadioImpl::setClir(int32_t serial, int32_t status) {
1179#if VDBG
1180    RLOGD("setClir: serial %d", serial);
1181#endif
1182    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_CLIR, 1, status);
1183    return Void();
1184}
1185
1186Return<void> RadioImpl::getCallForwardStatus(int32_t serial, const CallForwardInfo& callInfo) {
1187#if VDBG
1188    RLOGD("getCallForwardStatus: serial %d", serial);
1189#endif
1190    dispatchCallForwardStatus(serial, mSlotId, RIL_REQUEST_QUERY_CALL_FORWARD_STATUS,
1191            callInfo);
1192    return Void();
1193}
1194
1195Return<void> RadioImpl::setCallForward(int32_t serial, const CallForwardInfo& callInfo) {
1196#if VDBG
1197    RLOGD("setCallForward: serial %d", serial);
1198#endif
1199    dispatchCallForwardStatus(serial, mSlotId, RIL_REQUEST_SET_CALL_FORWARD,
1200            callInfo);
1201    return Void();
1202}
1203
1204Return<void> RadioImpl::getCallWaiting(int32_t serial, int32_t serviceClass) {
1205#if VDBG
1206    RLOGD("getCallWaiting: serial %d", serial);
1207#endif
1208    dispatchInts(serial, mSlotId, RIL_REQUEST_QUERY_CALL_WAITING, 1, serviceClass);
1209    return Void();
1210}
1211
1212Return<void> RadioImpl::setCallWaiting(int32_t serial, bool enable, int32_t serviceClass) {
1213#if VDBG
1214    RLOGD("setCallWaiting: serial %d", serial);
1215#endif
1216    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_CALL_WAITING, 2, BOOL_TO_INT(enable),
1217            serviceClass);
1218    return Void();
1219}
1220
1221Return<void> RadioImpl::acknowledgeLastIncomingGsmSms(int32_t serial,
1222                                                      bool success, SmsAcknowledgeFailCause cause) {
1223#if VDBG
1224    RLOGD("acknowledgeLastIncomingGsmSms: serial %d", serial);
1225#endif
1226    dispatchInts(serial, mSlotId, RIL_REQUEST_SMS_ACKNOWLEDGE, 2, BOOL_TO_INT(success),
1227            cause);
1228    return Void();
1229}
1230
1231Return<void> RadioImpl::acceptCall(int32_t serial) {
1232#if VDBG
1233    RLOGD("acceptCall: serial %d", serial);
1234#endif
1235    dispatchVoid(serial, mSlotId, RIL_REQUEST_ANSWER);
1236    return Void();
1237}
1238
1239Return<void> RadioImpl::deactivateDataCall(int32_t serial,
1240                                           int32_t cid, bool reasonRadioShutDown) {
1241#if VDBG
1242    RLOGD("deactivateDataCall: serial %d", serial);
1243#endif
1244    dispatchStrings(serial, mSlotId, RIL_REQUEST_DEACTIVATE_DATA_CALL,
1245            2, (std::to_string(cid)).c_str(), reasonRadioShutDown ? "1" : "0");
1246    return Void();
1247}
1248
1249Return<void> RadioImpl::getFacilityLockForApp(int32_t serial, const hidl_string& facility,
1250                                              const hidl_string& password, int32_t serviceClass,
1251                                              const hidl_string& appId) {
1252#if VDBG
1253    RLOGD("getFacilityLockForApp: serial %d", serial);
1254#endif
1255    dispatchStrings(serial, mSlotId, RIL_REQUEST_QUERY_FACILITY_LOCK,
1256            4, facility.c_str(), password.c_str(),
1257            (std::to_string(serviceClass)).c_str(), appId.c_str());
1258    return Void();
1259}
1260
1261Return<void> RadioImpl::setFacilityLockForApp(int32_t serial, const hidl_string& facility,
1262                                              bool lockState, const hidl_string& password,
1263                                              int32_t serviceClass, const hidl_string& appId) {
1264#if VDBG
1265    RLOGD("setFacilityLockForApp: serial %d", serial);
1266#endif
1267    dispatchStrings(serial, mSlotId, RIL_REQUEST_SET_FACILITY_LOCK,
1268            5, facility.c_str(), lockState ? "1" : "0", password.c_str(),
1269            (std::to_string(serviceClass)).c_str(), appId.c_str() );
1270    return Void();
1271}
1272
1273Return<void> RadioImpl::setBarringPassword(int32_t serial, const hidl_string& facility,
1274                                           const hidl_string& oldPassword,
1275                                           const hidl_string& newPassword) {
1276#if VDBG
1277    RLOGD("setBarringPassword: serial %d", serial);
1278#endif
1279    dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_BARRING_PASSWORD,
1280            3, facility.c_str(), oldPassword.c_str(), newPassword.c_str());
1281    return Void();
1282}
1283
1284Return<void> RadioImpl::getNetworkSelectionMode(int32_t serial) {
1285#if VDBG
1286    RLOGD("getNetworkSelectionMode: serial %d", serial);
1287#endif
1288    dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE);
1289    return Void();
1290}
1291
1292Return<void> RadioImpl::setNetworkSelectionModeAutomatic(int32_t serial) {
1293#if VDBG
1294    RLOGD("setNetworkSelectionModeAutomatic: serial %d", serial);
1295#endif
1296    dispatchVoid(serial, mSlotId, RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC);
1297    return Void();
1298}
1299
1300Return<void> RadioImpl::setNetworkSelectionModeManual(int32_t serial,
1301                                                      const hidl_string& operatorNumeric) {
1302#if VDBG
1303    RLOGD("setNetworkSelectionModeManual: serial %d", serial);
1304#endif
1305    dispatchString(serial, mSlotId, RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL,
1306            operatorNumeric.c_str());
1307    return Void();
1308}
1309
1310Return<void> RadioImpl::getAvailableNetworks(int32_t serial) {
1311#if VDBG
1312    RLOGD("getAvailableNetworks: serial %d", serial);
1313#endif
1314    dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_AVAILABLE_NETWORKS);
1315    return Void();
1316}
1317
1318Return<void> RadioImpl::startDtmf(int32_t serial, const hidl_string& s) {
1319#if VDBG
1320    RLOGD("startDtmf: serial %d", serial);
1321#endif
1322    dispatchString(serial, mSlotId, RIL_REQUEST_DTMF_START,
1323            s.c_str());
1324    return Void();
1325}
1326
1327Return<void> RadioImpl::stopDtmf(int32_t serial) {
1328#if VDBG
1329    RLOGD("stopDtmf: serial %d", serial);
1330#endif
1331    dispatchVoid(serial, mSlotId, RIL_REQUEST_DTMF_STOP);
1332    return Void();
1333}
1334
1335Return<void> RadioImpl::getBasebandVersion(int32_t serial) {
1336#if VDBG
1337    RLOGD("getBasebandVersion: serial %d", serial);
1338#endif
1339    dispatchVoid(serial, mSlotId, RIL_REQUEST_BASEBAND_VERSION);
1340    return Void();
1341}
1342
1343Return<void> RadioImpl::separateConnection(int32_t serial, int32_t gsmIndex) {
1344#if VDBG
1345    RLOGD("separateConnection: serial %d", serial);
1346#endif
1347    dispatchInts(serial, mSlotId, RIL_REQUEST_SEPARATE_CONNECTION, 1, gsmIndex);
1348    return Void();
1349}
1350
1351Return<void> RadioImpl::setMute(int32_t serial, bool enable) {
1352#if VDBG
1353    RLOGD("setMute: serial %d", serial);
1354#endif
1355    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_MUTE, 1, BOOL_TO_INT(enable));
1356    return Void();
1357}
1358
1359Return<void> RadioImpl::getMute(int32_t serial) {
1360#if VDBG
1361    RLOGD("getMute: serial %d", serial);
1362#endif
1363    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_MUTE);
1364    return Void();
1365}
1366
1367Return<void> RadioImpl::getClip(int32_t serial) {
1368#if VDBG
1369    RLOGD("getClip: serial %d", serial);
1370#endif
1371    dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_CLIP);
1372    return Void();
1373}
1374
1375Return<void> RadioImpl::getDataCallList(int32_t serial) {
1376#if VDBG
1377    RLOGD("getDataCallList: serial %d", serial);
1378#endif
1379    dispatchVoid(serial, mSlotId, RIL_REQUEST_DATA_CALL_LIST);
1380    return Void();
1381}
1382
1383Return<void> RadioImpl::setSuppServiceNotifications(int32_t serial, bool enable) {
1384#if VDBG
1385    RLOGD("setSuppServiceNotifications: serial %d", serial);
1386#endif
1387    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, 1,
1388            BOOL_TO_INT(enable));
1389    return Void();
1390}
1391
1392Return<void> RadioImpl::writeSmsToSim(int32_t serial, const SmsWriteArgs& smsWriteArgs) {
1393#if VDBG
1394    RLOGD("writeSmsToSim: serial %d", serial);
1395#endif
1396    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_WRITE_SMS_TO_SIM);
1397    if (pRI == NULL) {
1398        return Void();
1399    }
1400
1401    RIL_SMS_WriteArgs args;
1402    args.status = (int) smsWriteArgs.status;
1403
1404    int len;
1405    if (!copyHidlStringToRil(&args.pdu, smsWriteArgs.pdu, pRI)) {
1406        return Void();
1407    }
1408
1409    if (!copyHidlStringToRil(&args.smsc, smsWriteArgs.smsc, pRI)) {
1410        memsetAndFreeStrings(1, args.pdu);
1411        return Void();
1412    }
1413
1414    CALL_ONREQUEST(RIL_REQUEST_WRITE_SMS_TO_SIM, &args, sizeof(args), pRI, mSlotId);
1415
1416    memsetAndFreeStrings(2, args.smsc, args.pdu);
1417
1418    return Void();
1419}
1420
1421Return<void> RadioImpl::deleteSmsOnSim(int32_t serial, int32_t index) {
1422#if VDBG
1423    RLOGD("deleteSmsOnSim: serial %d", serial);
1424#endif
1425    dispatchInts(serial, mSlotId, RIL_REQUEST_DELETE_SMS_ON_SIM, 1, index);
1426    return Void();
1427}
1428
1429Return<void> RadioImpl::setBandMode(int32_t serial, RadioBandMode mode) {
1430#if VDBG
1431    RLOGD("setBandMode: serial %d", serial);
1432#endif
1433    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_BAND_MODE, 1, mode);
1434    return Void();
1435}
1436
1437Return<void> RadioImpl::getAvailableBandModes(int32_t serial) {
1438#if VDBG
1439    RLOGD("getAvailableBandModes: serial %d", serial);
1440#endif
1441    dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE);
1442    return Void();
1443}
1444
1445Return<void> RadioImpl::sendEnvelope(int32_t serial, const hidl_string& command) {
1446#if VDBG
1447    RLOGD("sendEnvelope: serial %d", serial);
1448#endif
1449    dispatchString(serial, mSlotId, RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND,
1450            command.c_str());
1451    return Void();
1452}
1453
1454Return<void> RadioImpl::sendTerminalResponseToSim(int32_t serial,
1455                                                  const hidl_string& commandResponse) {
1456#if VDBG
1457    RLOGD("sendTerminalResponseToSim: serial %d", serial);
1458#endif
1459    dispatchString(serial, mSlotId, RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE,
1460            commandResponse.c_str());
1461    return Void();
1462}
1463
1464Return<void> RadioImpl::handleStkCallSetupRequestFromSim(int32_t serial, bool accept) {
1465#if VDBG
1466    RLOGD("handleStkCallSetupRequestFromSim: serial %d", serial);
1467#endif
1468    dispatchInts(serial, mSlotId, RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM,
1469            1, BOOL_TO_INT(accept));
1470    return Void();
1471}
1472
1473Return<void> RadioImpl::explicitCallTransfer(int32_t serial) {
1474#if VDBG
1475    RLOGD("explicitCallTransfer: serial %d", serial);
1476#endif
1477    dispatchVoid(serial, mSlotId, RIL_REQUEST_EXPLICIT_CALL_TRANSFER);
1478    return Void();
1479}
1480
1481Return<void> RadioImpl::setPreferredNetworkType(int32_t serial, PreferredNetworkType nwType) {
1482#if VDBG
1483    RLOGD("setPreferredNetworkType: serial %d", serial);
1484#endif
1485    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, 1, nwType);
1486    return Void();
1487}
1488
1489Return<void> RadioImpl::getPreferredNetworkType(int32_t serial) {
1490#if VDBG
1491    RLOGD("getPreferredNetworkType: serial %d", serial);
1492#endif
1493    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE);
1494    return Void();
1495}
1496
1497Return<void> RadioImpl::getNeighboringCids(int32_t serial) {
1498#if VDBG
1499    RLOGD("getNeighboringCids: serial %d", serial);
1500#endif
1501    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_NEIGHBORING_CELL_IDS);
1502    return Void();
1503}
1504
1505Return<void> RadioImpl::setLocationUpdates(int32_t serial, bool enable) {
1506#if VDBG
1507    RLOGD("setLocationUpdates: serial %d", serial);
1508#endif
1509    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_LOCATION_UPDATES, 1, BOOL_TO_INT(enable));
1510    return Void();
1511}
1512
1513Return<void> RadioImpl::setCdmaSubscriptionSource(int32_t serial, CdmaSubscriptionSource cdmaSub) {
1514#if VDBG
1515    RLOGD("setCdmaSubscriptionSource: serial %d", serial);
1516#endif
1517    dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, 1, cdmaSub);
1518    return Void();
1519}
1520
1521Return<void> RadioImpl::setCdmaRoamingPreference(int32_t serial, CdmaRoamingType type) {
1522#if VDBG
1523    RLOGD("setCdmaRoamingPreference: serial %d", serial);
1524#endif
1525    dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, 1, type);
1526    return Void();
1527}
1528
1529Return<void> RadioImpl::getCdmaRoamingPreference(int32_t serial) {
1530#if VDBG
1531    RLOGD("getCdmaRoamingPreference: serial %d", serial);
1532#endif
1533    dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE);
1534    return Void();
1535}
1536
1537Return<void> RadioImpl::setTTYMode(int32_t serial, TtyMode mode) {
1538#if VDBG
1539    RLOGD("setTTYMode: serial %d", serial);
1540#endif
1541    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_TTY_MODE, 1, mode);
1542    return Void();
1543}
1544
1545Return<void> RadioImpl::getTTYMode(int32_t serial) {
1546#if VDBG
1547    RLOGD("getTTYMode: serial %d", serial);
1548#endif
1549    dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_TTY_MODE);
1550    return Void();
1551}
1552
1553Return<void> RadioImpl::setPreferredVoicePrivacy(int32_t serial, bool enable) {
1554#if VDBG
1555    RLOGD("setPreferredVoicePrivacy: serial %d", serial);
1556#endif
1557    dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE,
1558            1, BOOL_TO_INT(enable));
1559    return Void();
1560}
1561
1562Return<void> RadioImpl::getPreferredVoicePrivacy(int32_t serial) {
1563#if VDBG
1564    RLOGD("getPreferredVoicePrivacy: serial %d", serial);
1565#endif
1566    dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE);
1567    return Void();
1568}
1569
1570Return<void> RadioImpl::sendCDMAFeatureCode(int32_t serial, const hidl_string& featureCode) {
1571#if VDBG
1572    RLOGD("sendCDMAFeatureCode: serial %d", serial);
1573#endif
1574    dispatchString(serial, mSlotId, RIL_REQUEST_CDMA_FLASH,
1575            featureCode.c_str());
1576    return Void();
1577}
1578
1579Return<void> RadioImpl::sendBurstDtmf(int32_t serial, const hidl_string& dtmf, int32_t on,
1580                                      int32_t off) {
1581#if VDBG
1582    RLOGD("sendBurstDtmf: serial %d", serial);
1583#endif
1584    dispatchStrings(serial, mSlotId, RIL_REQUEST_CDMA_BURST_DTMF,
1585            3, dtmf.c_str(), (std::to_string(on)).c_str(),
1586            (std::to_string(off)).c_str());
1587    return Void();
1588}
1589
1590void constructCdmaSms(RIL_CDMA_SMS_Message &rcsm, const CdmaSmsMessage& sms) {
1591    rcsm.uTeleserviceID = sms.teleserviceId;
1592    rcsm.bIsServicePresent = BOOL_TO_INT(sms.isServicePresent);
1593    rcsm.uServicecategory = sms.serviceCategory;
1594    rcsm.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) sms.address.digitMode;
1595    rcsm.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) sms.address.numberMode;
1596    rcsm.sAddress.number_type = (RIL_CDMA_SMS_NumberType) sms.address.numberType;
1597    rcsm.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) sms.address.numberPlan;
1598
1599    rcsm.sAddress.number_of_digits = sms.address.digits.size();
1600    int digitLimit= MIN((rcsm.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
1601    for (int i = 0; i < digitLimit; i++) {
1602        rcsm.sAddress.digits[i] = sms.address.digits[i];
1603    }
1604
1605    rcsm.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) sms.subAddress.subaddressType;
1606    rcsm.sSubAddress.odd = BOOL_TO_INT(sms.subAddress.odd);
1607
1608    rcsm.sSubAddress.number_of_digits = sms.subAddress.digits.size();
1609    digitLimit= MIN((rcsm.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
1610    for (int i = 0; i < digitLimit; i++) {
1611        rcsm.sSubAddress.digits[i] = sms.subAddress.digits[i];
1612    }
1613
1614    rcsm.uBearerDataLen = sms.bearerData.size();
1615    digitLimit= MIN((rcsm.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
1616    for (int i = 0; i < digitLimit; i++) {
1617        rcsm.aBearerData[i] = sms.bearerData[i];
1618    }
1619}
1620
1621Return<void> RadioImpl::sendCdmaSms(int32_t serial, const CdmaSmsMessage& sms) {
1622#if VDBG
1623    RLOGD("sendCdmaSms: serial %d", serial);
1624#endif
1625    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_CDMA_SEND_SMS);
1626    if (pRI == NULL) {
1627        return Void();
1628    }
1629
1630    RIL_CDMA_SMS_Message rcsm = {};
1631    constructCdmaSms(rcsm, sms);
1632
1633    CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm), pRI, mSlotId);
1634    return Void();
1635}
1636
1637Return<void> RadioImpl::acknowledgeLastIncomingCdmaSms(int32_t serial, const CdmaSmsAck& smsAck) {
1638#if VDBG
1639    RLOGD("acknowledgeLastIncomingCdmaSms: serial %d", serial);
1640#endif
1641    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE);
1642    if (pRI == NULL) {
1643        return Void();
1644    }
1645
1646    RIL_CDMA_SMS_Ack rcsa = {};
1647
1648    rcsa.uErrorClass = (RIL_CDMA_SMS_ErrorClass) smsAck.errorClass;
1649    rcsa.uSMSCauseCode = smsAck.smsCauseCode;
1650
1651    CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa), pRI, mSlotId);
1652    return Void();
1653}
1654
1655Return<void> RadioImpl::getGsmBroadcastConfig(int32_t serial) {
1656#if VDBG
1657    RLOGD("getGsmBroadcastConfig: serial %d", serial);
1658#endif
1659    dispatchVoid(serial, mSlotId, RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG);
1660    return Void();
1661}
1662
1663Return<void> RadioImpl::setGsmBroadcastConfig(int32_t serial,
1664                                              const hidl_vec<GsmBroadcastSmsConfigInfo>&
1665                                              configInfo) {
1666#if VDBG
1667    RLOGD("setGsmBroadcastConfig: serial %d", serial);
1668#endif
1669    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
1670            RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG);
1671    if (pRI == NULL) {
1672        return Void();
1673    }
1674
1675    int num = configInfo.size();
1676    RIL_GSM_BroadcastSmsConfigInfo gsmBci[num];
1677    RIL_GSM_BroadcastSmsConfigInfo *gsmBciPtrs[num];
1678
1679    for (int i = 0 ; i < num ; i++ ) {
1680        gsmBciPtrs[i] = &gsmBci[i];
1681        gsmBci[i].fromServiceId = configInfo[i].fromServiceId;
1682        gsmBci[i].toServiceId = configInfo[i].toServiceId;
1683        gsmBci[i].fromCodeScheme = configInfo[i].fromCodeScheme;
1684        gsmBci[i].toCodeScheme = configInfo[i].toCodeScheme;
1685        gsmBci[i].selected = BOOL_TO_INT(configInfo[i].selected);
1686    }
1687
1688    CALL_ONREQUEST(pRI->pCI->requestNumber, gsmBciPtrs,
1689            num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *), pRI, mSlotId);
1690    return Void();
1691}
1692
1693Return<void> RadioImpl::setGsmBroadcastActivation(int32_t serial, bool activate) {
1694#if VDBG
1695    RLOGD("setGsmBroadcastActivation: serial %d", serial);
1696#endif
1697    dispatchInts(serial, mSlotId, RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION,
1698            1, BOOL_TO_INT(!activate));
1699    return Void();
1700}
1701
1702Return<void> RadioImpl::getCdmaBroadcastConfig(int32_t serial) {
1703#if VDBG
1704    RLOGD("getCdmaBroadcastConfig: serial %d", serial);
1705#endif
1706    dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG);
1707    return Void();
1708}
1709
1710Return<void> RadioImpl::setCdmaBroadcastConfig(int32_t serial,
1711                                               const hidl_vec<CdmaBroadcastSmsConfigInfo>&
1712                                               configInfo) {
1713#if VDBG
1714    RLOGD("setCdmaBroadcastConfig: serial %d", serial);
1715#endif
1716    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
1717            RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG);
1718    if (pRI == NULL) {
1719        return Void();
1720    }
1721
1722    int num = configInfo.size();
1723    RIL_CDMA_BroadcastSmsConfigInfo cdmaBci[num];
1724    RIL_CDMA_BroadcastSmsConfigInfo *cdmaBciPtrs[num];
1725
1726    for (int i = 0 ; i < num ; i++ ) {
1727        cdmaBciPtrs[i] = &cdmaBci[i];
1728        cdmaBci[i].service_category = configInfo[i].serviceCategory;
1729        cdmaBci[i].language = configInfo[i].language;
1730        cdmaBci[i].selected = BOOL_TO_INT(configInfo[i].selected);
1731    }
1732
1733    CALL_ONREQUEST(pRI->pCI->requestNumber, cdmaBciPtrs,
1734            num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *), pRI, mSlotId);
1735    return Void();
1736}
1737
1738Return<void> RadioImpl::setCdmaBroadcastActivation(int32_t serial, bool activate) {
1739#if VDBG
1740    RLOGD("setCdmaBroadcastActivation: serial %d", serial);
1741#endif
1742    dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION,
1743            1, BOOL_TO_INT(!activate));
1744    return Void();
1745}
1746
1747Return<void> RadioImpl::getCDMASubscription(int32_t serial) {
1748#if VDBG
1749    RLOGD("getCDMASubscription: serial %d", serial);
1750#endif
1751    dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_SUBSCRIPTION);
1752    return Void();
1753}
1754
1755Return<void> RadioImpl::writeSmsToRuim(int32_t serial, const CdmaSmsWriteArgs& cdmaSms) {
1756#if VDBG
1757    RLOGD("writeSmsToRuim: serial %d", serial);
1758#endif
1759    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
1760            RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM);
1761    if (pRI == NULL) {
1762        return Void();
1763    }
1764
1765    RIL_CDMA_SMS_WriteArgs rcsw = {};
1766    rcsw.status = (int) cdmaSms.status;
1767    constructCdmaSms(rcsw.message, cdmaSms.message);
1768
1769    CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw), pRI, mSlotId);
1770    return Void();
1771}
1772
1773Return<void> RadioImpl::deleteSmsOnRuim(int32_t serial, int32_t index) {
1774#if VDBG
1775    RLOGD("deleteSmsOnRuim: serial %d", serial);
1776#endif
1777    dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, 1, index);
1778    return Void();
1779}
1780
1781Return<void> RadioImpl::getDeviceIdentity(int32_t serial) {
1782#if VDBG
1783    RLOGD("getDeviceIdentity: serial %d", serial);
1784#endif
1785    dispatchVoid(serial, mSlotId, RIL_REQUEST_DEVICE_IDENTITY);
1786    return Void();
1787}
1788
1789Return<void> RadioImpl::exitEmergencyCallbackMode(int32_t serial) {
1790#if VDBG
1791    RLOGD("exitEmergencyCallbackMode: serial %d", serial);
1792#endif
1793    dispatchVoid(serial, mSlotId, RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE);
1794    return Void();
1795}
1796
1797Return<void> RadioImpl::getSmscAddress(int32_t serial) {
1798#if VDBG
1799    RLOGD("getSmscAddress: serial %d", serial);
1800#endif
1801    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_SMSC_ADDRESS);
1802    return Void();
1803}
1804
1805Return<void> RadioImpl::setSmscAddress(int32_t serial, const hidl_string& smsc) {
1806#if VDBG
1807    RLOGD("setSmscAddress: serial %d", serial);
1808#endif
1809    dispatchString(serial, mSlotId, RIL_REQUEST_SET_SMSC_ADDRESS,
1810            smsc.c_str());
1811    return Void();
1812}
1813
1814Return<void> RadioImpl::reportSmsMemoryStatus(int32_t serial, bool available) {
1815#if VDBG
1816    RLOGD("reportSmsMemoryStatus: serial %d", serial);
1817#endif
1818    dispatchInts(serial, mSlotId, RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, 1,
1819            BOOL_TO_INT(available));
1820    return Void();
1821}
1822
1823Return<void> RadioImpl::reportStkServiceIsRunning(int32_t serial) {
1824#if VDBG
1825    RLOGD("reportStkServiceIsRunning: serial %d", serial);
1826#endif
1827    dispatchVoid(serial, mSlotId, RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING);
1828    return Void();
1829}
1830
1831Return<void> RadioImpl::getCdmaSubscriptionSource(int32_t serial) {
1832#if VDBG
1833    RLOGD("getCdmaSubscriptionSource: serial %d", serial);
1834#endif
1835    dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE);
1836    return Void();
1837}
1838
1839Return<void> RadioImpl::requestIsimAuthentication(int32_t serial, const hidl_string& challenge) {
1840#if VDBG
1841    RLOGD("requestIsimAuthentication: serial %d", serial);
1842#endif
1843    dispatchString(serial, mSlotId, RIL_REQUEST_ISIM_AUTHENTICATION,
1844            challenge.c_str());
1845    return Void();
1846}
1847
1848Return<void> RadioImpl::acknowledgeIncomingGsmSmsWithPdu(int32_t serial, bool success,
1849                                                         const hidl_string& ackPdu) {
1850#if VDBG
1851    RLOGD("acknowledgeIncomingGsmSmsWithPdu: serial %d", serial);
1852#endif
1853    dispatchStrings(serial, mSlotId, RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU,
1854            2, success ? "1" : "0", ackPdu.c_str());
1855    return Void();
1856}
1857
1858Return<void> RadioImpl::sendEnvelopeWithStatus(int32_t serial, const hidl_string& contents) {
1859#if VDBG
1860    RLOGD("sendEnvelopeWithStatus: serial %d", serial);
1861#endif
1862    dispatchString(serial, mSlotId, RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS,
1863            contents.c_str());
1864    return Void();
1865}
1866
1867Return<void> RadioImpl::getVoiceRadioTechnology(int32_t serial) {
1868#if VDBG
1869    RLOGD("getVoiceRadioTechnology: serial %d", serial);
1870#endif
1871    dispatchVoid(serial, mSlotId, RIL_REQUEST_VOICE_RADIO_TECH);
1872    return Void();
1873}
1874
1875Return<void> RadioImpl::getCellInfoList(int32_t serial) {
1876#if VDBG
1877    RLOGD("getCellInfoList: serial %d", serial);
1878#endif
1879    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CELL_INFO_LIST);
1880    return Void();
1881}
1882
1883Return<void> RadioImpl::setCellInfoListRate(int32_t serial, int32_t rate) {
1884#if VDBG
1885    RLOGD("setCellInfoListRate: serial %d", serial);
1886#endif
1887    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, 1, rate);
1888    return Void();
1889}
1890
1891Return<void> RadioImpl::setInitialAttachApn(int32_t serial, const DataProfileInfo& dataProfileInfo,
1892                                            bool modemCognitive, bool isRoaming) {
1893#if VDBG
1894    RLOGD("setInitialAttachApn: serial %d", serial);
1895#endif
1896    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
1897            RIL_REQUEST_SET_INITIAL_ATTACH_APN);
1898    if (pRI == NULL) {
1899        return Void();
1900    }
1901
1902    if (s_vendorFunctions->version <= 14) {
1903        RIL_InitialAttachApn iaa = {};
1904
1905        if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI)) {
1906            return Void();
1907        }
1908
1909        const hidl_string &protocol =
1910                (isRoaming ? dataProfileInfo.roamingProtocol : dataProfileInfo.protocol);
1911
1912        if (!copyHidlStringToRil(&iaa.protocol, protocol, pRI)) {
1913            memsetAndFreeStrings(1, iaa.apn);
1914            return Void();
1915        }
1916        iaa.authtype = (int) dataProfileInfo.authType;
1917        if (!copyHidlStringToRil(&iaa.username, dataProfileInfo.user, pRI)) {
1918            memsetAndFreeStrings(2, iaa.apn, iaa.protocol);
1919            return Void();
1920        }
1921        if (!copyHidlStringToRil(&iaa.password, dataProfileInfo.password, pRI)) {
1922            memsetAndFreeStrings(3, iaa.apn, iaa.protocol, iaa.username);
1923            return Void();
1924        }
1925
1926        CALL_ONREQUEST(RIL_REQUEST_SET_INITIAL_ATTACH_APN, &iaa, sizeof(iaa), pRI, mSlotId);
1927
1928        memsetAndFreeStrings(4, iaa.apn, iaa.protocol, iaa.username, iaa.password);
1929    } else {
1930        RIL_InitialAttachApn_v15 iaa = {};
1931
1932        if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI)) {
1933            return Void();
1934        }
1935        if (!copyHidlStringToRil(&iaa.protocol, dataProfileInfo.protocol, pRI)) {
1936            memsetAndFreeStrings(1, iaa.apn);
1937            return Void();
1938        }
1939        if (!copyHidlStringToRil(&iaa.roamingProtocol, dataProfileInfo.roamingProtocol, pRI)) {
1940            memsetAndFreeStrings(2, iaa.apn, iaa.protocol);
1941            return Void();
1942        }
1943        iaa.authtype = (int) dataProfileInfo.authType;
1944        if (!copyHidlStringToRil(&iaa.username, dataProfileInfo.user, pRI)) {
1945            memsetAndFreeStrings(3, iaa.apn, iaa.protocol, iaa.roamingProtocol);
1946            return Void();
1947        }
1948        if (!copyHidlStringToRil(&iaa.password, dataProfileInfo.password, pRI)) {
1949            memsetAndFreeStrings(4, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username);
1950            return Void();
1951        }
1952        iaa.supportedTypesBitmask = dataProfileInfo.supportedApnTypesBitmap;
1953        iaa.bearerBitmask = dataProfileInfo.bearerBitmap;
1954        iaa.modemCognitive = BOOL_TO_INT(modemCognitive);
1955        iaa.mtu = dataProfileInfo.mtu;
1956
1957        if (!convertMvnoTypeToString(dataProfileInfo.mvnoType, iaa.mvnoType)) {
1958            sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
1959            memsetAndFreeStrings(5, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username,
1960                    iaa.password);
1961            return Void();
1962        }
1963
1964        if (!copyHidlStringToRil(&iaa.mvnoMatchData, dataProfileInfo.mvnoMatchData, pRI)) {
1965            memsetAndFreeStrings(5, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username,
1966                    iaa.password);
1967            return Void();
1968        }
1969
1970        CALL_ONREQUEST(RIL_REQUEST_SET_INITIAL_ATTACH_APN, &iaa, sizeof(iaa), pRI, mSlotId);
1971
1972        memsetAndFreeStrings(6, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username,
1973                iaa.password, iaa.mvnoMatchData);
1974    }
1975
1976    return Void();
1977}
1978
1979Return<void> RadioImpl::getImsRegistrationState(int32_t serial) {
1980#if VDBG
1981    RLOGD("getImsRegistrationState: serial %d", serial);
1982#endif
1983    dispatchVoid(serial, mSlotId, RIL_REQUEST_IMS_REGISTRATION_STATE);
1984    return Void();
1985}
1986
1987bool dispatchImsGsmSms(const ImsSmsMessage& message, RequestInfo *pRI) {
1988    RIL_IMS_SMS_Message rism = {};
1989    char **pStrings;
1990    int countStrings = 2;
1991    int dataLen = sizeof(char *) * countStrings;
1992
1993    rism.tech = RADIO_TECH_3GPP;
1994    rism.retry = BOOL_TO_INT(message.retry);
1995    rism.messageRef = message.messageRef;
1996
1997    if (message.gsmMessage.size() != 1) {
1998        RLOGE("dispatchImsGsmSms: Invalid len %s", requestToString(pRI->pCI->requestNumber));
1999        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
2000        return false;
2001    }
2002
2003    pStrings = (char **)calloc(countStrings, sizeof(char *));
2004    if (pStrings == NULL) {
2005        RLOGE("dispatchImsGsmSms: Memory allocation failed for request %s",
2006                requestToString(pRI->pCI->requestNumber));
2007        sendErrorResponse(pRI, RIL_E_NO_MEMORY);
2008        return false;
2009    }
2010
2011    if (!copyHidlStringToRil(&pStrings[0], message.gsmMessage[0].smscPdu, pRI)) {
2012#ifdef MEMSET_FREED
2013        memset(pStrings, 0, datalen);
2014#endif
2015        free(pStrings);
2016        return false;
2017    }
2018
2019    if (!copyHidlStringToRil(&pStrings[1], message.gsmMessage[0].pdu, pRI)) {
2020        memsetAndFreeStrings(1, pStrings[0]);
2021#ifdef MEMSET_FREED
2022        memset(pStrings, 0, datalen);
2023#endif
2024        free(pStrings);
2025        return false;
2026    }
2027
2028    rism.message.gsmMessage = pStrings;
2029    CALL_ONREQUEST(pRI->pCI->requestNumber, &rism, sizeof(RIL_RadioTechnologyFamily) +
2030            sizeof(uint8_t) + sizeof(int32_t) + dataLen, pRI, pRI->socket_id);
2031
2032    for (int i = 0 ; i < countStrings ; i++) {
2033        memsetAndFreeStrings(1, pStrings[i]);
2034    }
2035
2036#ifdef MEMSET_FREED
2037    memset(pStrings, 0, datalen);
2038#endif
2039    free(pStrings);
2040
2041    return true;
2042}
2043
2044bool dispatchImsCdmaSms(const ImsSmsMessage& message, RequestInfo *pRI) {
2045    RIL_IMS_SMS_Message rism = {};
2046    RIL_CDMA_SMS_Message rcsm = {};
2047
2048    if (message.cdmaMessage.size() != 1) {
2049        RLOGE("dispatchImsCdmaSms: Invalid len %s", requestToString(pRI->pCI->requestNumber));
2050        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
2051        return false;
2052    }
2053
2054    rism.tech = RADIO_TECH_3GPP2;
2055    rism.retry = BOOL_TO_INT(message.retry);
2056    rism.messageRef = message.messageRef;
2057    rism.message.cdmaMessage = &rcsm;
2058
2059    constructCdmaSms(rcsm, message.cdmaMessage[0]);
2060
2061    CALL_ONREQUEST(pRI->pCI->requestNumber, &rism, sizeof(RIL_RadioTechnologyFamily) +
2062            sizeof(uint8_t) + sizeof(int32_t) + sizeof(rcsm), pRI, pRI->socket_id);
2063
2064    return true;
2065}
2066
2067Return<void> RadioImpl::sendImsSms(int32_t serial, const ImsSmsMessage& message) {
2068#if VDBG
2069    RLOGD("sendImsSms: serial %d", serial);
2070#endif
2071    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_IMS_SEND_SMS);
2072    if (pRI == NULL) {
2073        return Void();
2074    }
2075
2076    RIL_RadioTechnologyFamily format = (RIL_RadioTechnologyFamily) message.tech;
2077
2078    if (RADIO_TECH_3GPP == format) {
2079        dispatchImsGsmSms(message, pRI);
2080    } else if (RADIO_TECH_3GPP2 == format) {
2081        dispatchImsCdmaSms(message, pRI);
2082    } else {
2083        RLOGE("sendImsSms: Invalid radio tech %s",
2084                requestToString(pRI->pCI->requestNumber));
2085        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
2086    }
2087    return Void();
2088}
2089
2090Return<void> RadioImpl::iccTransmitApduBasicChannel(int32_t serial, const SimApdu& message) {
2091#if VDBG
2092    RLOGD("iccTransmitApduBasicChannel: serial %d", serial);
2093#endif
2094    dispatchIccApdu(serial, mSlotId, RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, message);
2095    return Void();
2096}
2097
2098Return<void> RadioImpl::iccOpenLogicalChannel(int32_t serial, const hidl_string& aid, int32_t p2) {
2099#if VDBG
2100    RLOGD("iccOpenLogicalChannel: serial %d", serial);
2101#endif
2102    if (s_vendorFunctions->version < 15) {
2103        dispatchString(serial, mSlotId, RIL_REQUEST_SIM_OPEN_CHANNEL, aid.c_str());
2104    } else {
2105        RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SIM_OPEN_CHANNEL);
2106        if (pRI == NULL) {
2107            return Void();
2108        }
2109
2110        RIL_OpenChannelParams params = {};
2111
2112        params.p2 = p2;
2113
2114        if (!copyHidlStringToRil(&params.aidPtr, aid, pRI)) {
2115            return Void();
2116        }
2117
2118        CALL_ONREQUEST(pRI->pCI->requestNumber, &params, sizeof(params), pRI, mSlotId);
2119
2120        memsetAndFreeStrings(1, params.aidPtr);
2121    }
2122    return Void();
2123}
2124
2125Return<void> RadioImpl::iccCloseLogicalChannel(int32_t serial, int32_t channelId) {
2126#if VDBG
2127    RLOGD("iccCloseLogicalChannel: serial %d", serial);
2128#endif
2129    dispatchInts(serial, mSlotId, RIL_REQUEST_SIM_CLOSE_CHANNEL, 1, channelId);
2130    return Void();
2131}
2132
2133Return<void> RadioImpl::iccTransmitApduLogicalChannel(int32_t serial, const SimApdu& message) {
2134#if VDBG
2135    RLOGD("iccTransmitApduLogicalChannel: serial %d", serial);
2136#endif
2137    dispatchIccApdu(serial, mSlotId, RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, message);
2138    return Void();
2139}
2140
2141Return<void> RadioImpl::nvReadItem(int32_t serial, NvItem itemId) {
2142#if VDBG
2143    RLOGD("nvReadItem: serial %d", serial);
2144#endif
2145    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_NV_READ_ITEM);
2146    if (pRI == NULL) {
2147        return Void();
2148    }
2149
2150    RIL_NV_ReadItem nvri = {};
2151    nvri.itemID = (RIL_NV_Item) itemId;
2152
2153    CALL_ONREQUEST(pRI->pCI->requestNumber, &nvri, sizeof(nvri), pRI, mSlotId);
2154    return Void();
2155}
2156
2157Return<void> RadioImpl::nvWriteItem(int32_t serial, const NvWriteItem& item) {
2158#if VDBG
2159    RLOGD("nvWriteItem: serial %d", serial);
2160#endif
2161    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_NV_WRITE_ITEM);
2162    if (pRI == NULL) {
2163        return Void();
2164    }
2165
2166    RIL_NV_WriteItem nvwi = {};
2167
2168    nvwi.itemID = (RIL_NV_Item) item.itemId;
2169
2170    if (!copyHidlStringToRil(&nvwi.value, item.value, pRI)) {
2171        return Void();
2172    }
2173
2174    CALL_ONREQUEST(pRI->pCI->requestNumber, &nvwi, sizeof(nvwi), pRI, mSlotId);
2175
2176    memsetAndFreeStrings(1, nvwi.value);
2177    return Void();
2178}
2179
2180Return<void> RadioImpl::nvWriteCdmaPrl(int32_t serial, const hidl_vec<uint8_t>& prl) {
2181#if VDBG
2182    RLOGD("nvWriteCdmaPrl: serial %d", serial);
2183#endif
2184    dispatchRaw(serial, mSlotId, RIL_REQUEST_NV_WRITE_CDMA_PRL, prl);
2185    return Void();
2186}
2187
2188Return<void> RadioImpl::nvResetConfig(int32_t serial, ResetNvType resetType) {
2189    int rilResetType = -1;
2190#if VDBG
2191    RLOGD("nvResetConfig: serial %d", serial);
2192#endif
2193    /* Convert ResetNvType to RIL.h values
2194     * RIL_REQUEST_NV_RESET_CONFIG
2195     * 1 - reload all NV items
2196     * 2 - erase NV reset (SCRTN)
2197     * 3 - factory reset (RTN)
2198     */
2199    switch(resetType) {
2200      case ResetNvType::RELOAD:
2201        rilResetType = 1;
2202        break;
2203      case ResetNvType::ERASE:
2204        rilResetType = 2;
2205        break;
2206      case ResetNvType::FACTORY_RESET:
2207        rilResetType = 3;
2208        break;
2209    }
2210    dispatchInts(serial, mSlotId, RIL_REQUEST_NV_RESET_CONFIG, 1, rilResetType);
2211    return Void();
2212}
2213
2214Return<void> RadioImpl::setUiccSubscription(int32_t serial, const SelectUiccSub& uiccSub) {
2215#if VDBG
2216    RLOGD("setUiccSubscription: serial %d", serial);
2217#endif
2218    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
2219            RIL_REQUEST_SET_UICC_SUBSCRIPTION);
2220    if (pRI == NULL) {
2221        return Void();
2222    }
2223
2224    RIL_SelectUiccSub rilUiccSub = {};
2225
2226    rilUiccSub.slot = uiccSub.slot;
2227    rilUiccSub.app_index = uiccSub.appIndex;
2228    rilUiccSub.sub_type = (RIL_SubscriptionType) uiccSub.subType;
2229    rilUiccSub.act_status = (RIL_UiccSubActStatus) uiccSub.actStatus;
2230
2231    CALL_ONREQUEST(pRI->pCI->requestNumber, &rilUiccSub, sizeof(rilUiccSub), pRI, mSlotId);
2232    return Void();
2233}
2234
2235Return<void> RadioImpl::setDataAllowed(int32_t serial, bool allow) {
2236#if VDBG
2237    RLOGD("setDataAllowed: serial %d", serial);
2238#endif
2239    dispatchInts(serial, mSlotId, RIL_REQUEST_ALLOW_DATA, 1, BOOL_TO_INT(allow));
2240    return Void();
2241}
2242
2243Return<void> RadioImpl::getHardwareConfig(int32_t serial) {
2244#if VDBG
2245    RLOGD("getHardwareConfig: serial %d", serial);
2246#endif
2247    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_HARDWARE_CONFIG);
2248    return Void();
2249}
2250
2251Return<void> RadioImpl::requestIccSimAuthentication(int32_t serial, int32_t authContext,
2252        const hidl_string& authData, const hidl_string& aid) {
2253#if VDBG
2254    RLOGD("requestIccSimAuthentication: serial %d", serial);
2255#endif
2256    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SIM_AUTHENTICATION);
2257    if (pRI == NULL) {
2258        return Void();
2259    }
2260
2261    RIL_SimAuthentication pf = {};
2262
2263    pf.authContext = authContext;
2264
2265    int len;
2266    if (!copyHidlStringToRil(&pf.authData, authData, pRI)) {
2267        return Void();
2268    }
2269
2270    if (!copyHidlStringToRil(&pf.aid, aid, pRI)) {
2271        memsetAndFreeStrings(1, pf.authData);
2272        return Void();
2273    }
2274
2275    CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, mSlotId);
2276
2277    memsetAndFreeStrings(2, pf.authData, pf.aid);
2278    return Void();
2279}
2280
2281/**
2282 * @param numProfiles number of data profile
2283 * @param dataProfiles the pointer to the actual data profiles. The acceptable type is
2284          RIL_DataProfileInfo or RIL_DataProfileInfo_v15.
2285 * @param dataProfilePtrs the pointer to the pointers that point to each data profile structure
2286 * @param numfields number of string-type member in the data profile structure
2287 * @param ... the variadic parameters are pointers to each string-type member
2288 **/
2289template <typename T>
2290void freeSetDataProfileData(int numProfiles, T *dataProfiles, T **dataProfilePtrs,
2291                            int numfields, ...) {
2292    va_list args;
2293    va_start(args, numfields);
2294
2295    // Iterate through each string-type field that need to be free.
2296    for (int i = 0; i < numfields; i++) {
2297        // Iterate through each data profile and free that specific string-type field.
2298        // The type 'char *T::*' is a type of pointer to a 'char *' member inside T structure.
2299        char *T::*ptr = va_arg(args, char *T::*);
2300        for (int j = 0; j < numProfiles; j++) {
2301            memsetAndFreeStrings(1, dataProfiles[j].*ptr);
2302        }
2303    }
2304
2305    va_end(args);
2306
2307#ifdef MEMSET_FREED
2308    memset(dataProfiles, 0, numProfiles * sizeof(T));
2309    memset(dataProfilePtrs, 0, numProfiles * sizeof(T *));
2310#endif
2311    free(dataProfiles);
2312    free(dataProfilePtrs);
2313}
2314
2315Return<void> RadioImpl::setDataProfile(int32_t serial, const hidl_vec<DataProfileInfo>& profiles,
2316                                       bool isRoaming) {
2317#if VDBG
2318    RLOGD("setDataProfile: serial %d", serial);
2319#endif
2320    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SET_DATA_PROFILE);
2321    if (pRI == NULL) {
2322        return Void();
2323    }
2324
2325    size_t num = profiles.size();
2326    bool success = false;
2327
2328    if (s_vendorFunctions->version <= 14) {
2329
2330        RIL_DataProfileInfo *dataProfiles =
2331            (RIL_DataProfileInfo *) calloc(num, sizeof(RIL_DataProfileInfo));
2332
2333        if (dataProfiles == NULL) {
2334            RLOGE("Memory allocation failed for request %s",
2335                    requestToString(pRI->pCI->requestNumber));
2336            sendErrorResponse(pRI, RIL_E_NO_MEMORY);
2337            return Void();
2338        }
2339
2340        RIL_DataProfileInfo **dataProfilePtrs =
2341            (RIL_DataProfileInfo **) calloc(num, sizeof(RIL_DataProfileInfo *));
2342        if (dataProfilePtrs == NULL) {
2343            RLOGE("Memory allocation failed for request %s",
2344                    requestToString(pRI->pCI->requestNumber));
2345            free(dataProfiles);
2346            sendErrorResponse(pRI, RIL_E_NO_MEMORY);
2347            return Void();
2348        }
2349
2350        for (size_t i = 0; i < num; i++) {
2351            dataProfilePtrs[i] = &dataProfiles[i];
2352
2353            success = copyHidlStringToRil(&dataProfiles[i].apn, profiles[i].apn, pRI);
2354
2355            const hidl_string &protocol =
2356                    (isRoaming ? profiles[i].roamingProtocol : profiles[i].protocol);
2357
2358            if (success && !copyHidlStringToRil(&dataProfiles[i].protocol, protocol, pRI)) {
2359                success = false;
2360            }
2361
2362            if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI)) {
2363                success = false;
2364            }
2365            if (success && !copyHidlStringToRil(&dataProfiles[i].password, profiles[i].password,
2366                    pRI)) {
2367                success = false;
2368            }
2369
2370            if (!success) {
2371                freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 4,
2372                    &RIL_DataProfileInfo::apn, &RIL_DataProfileInfo::protocol,
2373                    &RIL_DataProfileInfo::user, &RIL_DataProfileInfo::password);
2374                return Void();
2375            }
2376
2377            dataProfiles[i].profileId = (RIL_DataProfile) profiles[i].profileId;
2378            dataProfiles[i].authType = (int) profiles[i].authType;
2379            dataProfiles[i].type = (int) profiles[i].type;
2380            dataProfiles[i].maxConnsTime = profiles[i].maxConnsTime;
2381            dataProfiles[i].maxConns = profiles[i].maxConns;
2382            dataProfiles[i].waitTime = profiles[i].waitTime;
2383            dataProfiles[i].enabled = BOOL_TO_INT(profiles[i].enabled);
2384        }
2385
2386        CALL_ONREQUEST(RIL_REQUEST_SET_DATA_PROFILE, dataProfilePtrs,
2387                num * sizeof(RIL_DataProfileInfo *), pRI, mSlotId);
2388
2389        freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 4,
2390                &RIL_DataProfileInfo::apn, &RIL_DataProfileInfo::protocol,
2391                &RIL_DataProfileInfo::user, &RIL_DataProfileInfo::password);
2392    } else {
2393        RIL_DataProfileInfo_v15 *dataProfiles =
2394            (RIL_DataProfileInfo_v15 *) calloc(num, sizeof(RIL_DataProfileInfo_v15));
2395
2396        if (dataProfiles == NULL) {
2397            RLOGE("Memory allocation failed for request %s",
2398                    requestToString(pRI->pCI->requestNumber));
2399            sendErrorResponse(pRI, RIL_E_NO_MEMORY);
2400            return Void();
2401        }
2402
2403        RIL_DataProfileInfo_v15 **dataProfilePtrs =
2404            (RIL_DataProfileInfo_v15 **) calloc(num, sizeof(RIL_DataProfileInfo_v15 *));
2405        if (dataProfilePtrs == NULL) {
2406            RLOGE("Memory allocation failed for request %s",
2407                    requestToString(pRI->pCI->requestNumber));
2408            free(dataProfiles);
2409            sendErrorResponse(pRI, RIL_E_NO_MEMORY);
2410            return Void();
2411        }
2412
2413        for (size_t i = 0; i < num; i++) {
2414            dataProfilePtrs[i] = &dataProfiles[i];
2415
2416            success = copyHidlStringToRil(&dataProfiles[i].apn, profiles[i].apn, pRI);
2417            if (success && !copyHidlStringToRil(&dataProfiles[i].protocol, profiles[i].protocol,
2418                    pRI)) {
2419                success = false;
2420            }
2421            if (success && !copyHidlStringToRil(&dataProfiles[i].roamingProtocol,
2422                    profiles[i].roamingProtocol, pRI)) {
2423                success = false;
2424            }
2425            if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI)) {
2426                success = false;
2427            }
2428            if (success && !copyHidlStringToRil(&dataProfiles[i].password, profiles[i].password,
2429                    pRI)) {
2430                success = false;
2431            }
2432
2433            if (success && !copyHidlStringToRil(&dataProfiles[i].mvnoMatchData,
2434                    profiles[i].mvnoMatchData, pRI)) {
2435                success = false;
2436            }
2437
2438            if (success && !convertMvnoTypeToString(profiles[i].mvnoType,
2439                    dataProfiles[i].mvnoType)) {
2440                sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
2441                success = false;
2442            }
2443
2444            if (!success) {
2445                freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 6,
2446                    &RIL_DataProfileInfo_v15::apn, &RIL_DataProfileInfo_v15::protocol,
2447                    &RIL_DataProfileInfo_v15::roamingProtocol, &RIL_DataProfileInfo_v15::user,
2448                    &RIL_DataProfileInfo_v15::password, &RIL_DataProfileInfo_v15::mvnoMatchData);
2449                return Void();
2450            }
2451
2452            dataProfiles[i].profileId = (RIL_DataProfile) profiles[i].profileId;
2453            dataProfiles[i].authType = (int) profiles[i].authType;
2454            dataProfiles[i].type = (int) profiles[i].type;
2455            dataProfiles[i].maxConnsTime = profiles[i].maxConnsTime;
2456            dataProfiles[i].maxConns = profiles[i].maxConns;
2457            dataProfiles[i].waitTime = profiles[i].waitTime;
2458            dataProfiles[i].enabled = BOOL_TO_INT(profiles[i].enabled);
2459            dataProfiles[i].supportedTypesBitmask = profiles[i].supportedApnTypesBitmap;
2460            dataProfiles[i].bearerBitmask = profiles[i].bearerBitmap;
2461            dataProfiles[i].mtu = profiles[i].mtu;
2462        }
2463
2464        CALL_ONREQUEST(RIL_REQUEST_SET_DATA_PROFILE, dataProfilePtrs,
2465                num * sizeof(RIL_DataProfileInfo_v15 *), pRI, mSlotId);
2466
2467        freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 6,
2468                &RIL_DataProfileInfo_v15::apn, &RIL_DataProfileInfo_v15::protocol,
2469                &RIL_DataProfileInfo_v15::roamingProtocol, &RIL_DataProfileInfo_v15::user,
2470                &RIL_DataProfileInfo_v15::password, &RIL_DataProfileInfo_v15::mvnoMatchData);
2471    }
2472
2473    return Void();
2474}
2475
2476Return<void> RadioImpl::requestShutdown(int32_t serial) {
2477#if VDBG
2478    RLOGD("requestShutdown: serial %d", serial);
2479#endif
2480    dispatchVoid(serial, mSlotId, RIL_REQUEST_SHUTDOWN);
2481    return Void();
2482}
2483
2484Return<void> RadioImpl::getRadioCapability(int32_t serial) {
2485#if VDBG
2486    RLOGD("getRadioCapability: serial %d", serial);
2487#endif
2488    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_RADIO_CAPABILITY);
2489    return Void();
2490}
2491
2492Return<void> RadioImpl::setRadioCapability(int32_t serial, const RadioCapability& rc) {
2493#if VDBG
2494    RLOGD("setRadioCapability: serial %d", serial);
2495#endif
2496    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SET_RADIO_CAPABILITY);
2497    if (pRI == NULL) {
2498        return Void();
2499    }
2500
2501    RIL_RadioCapability rilRc = {};
2502
2503    // TODO : set rilRc.version using HIDL version ?
2504    rilRc.session = rc.session;
2505    rilRc.phase = (int) rc.phase;
2506    rilRc.rat = (int) rc.raf;
2507    rilRc.status = (int) rc.status;
2508    strncpy(rilRc.logicalModemUuid, rc.logicalModemUuid.c_str(), MAX_UUID_LENGTH);
2509
2510    CALL_ONREQUEST(pRI->pCI->requestNumber, &rilRc, sizeof(rilRc), pRI, mSlotId);
2511
2512    return Void();
2513}
2514
2515Return<void> RadioImpl::startLceService(int32_t serial, int32_t reportInterval, bool pullMode) {
2516#if VDBG
2517    RLOGD("startLceService: serial %d", serial);
2518#endif
2519    dispatchInts(serial, mSlotId, RIL_REQUEST_START_LCE, 2, reportInterval,
2520            BOOL_TO_INT(pullMode));
2521    return Void();
2522}
2523
2524Return<void> RadioImpl::stopLceService(int32_t serial) {
2525#if VDBG
2526    RLOGD("stopLceService: serial %d", serial);
2527#endif
2528    dispatchVoid(serial, mSlotId, RIL_REQUEST_STOP_LCE);
2529    return Void();
2530}
2531
2532Return<void> RadioImpl::pullLceData(int32_t serial) {
2533#if VDBG
2534    RLOGD("pullLceData: serial %d", serial);
2535#endif
2536    dispatchVoid(serial, mSlotId, RIL_REQUEST_PULL_LCEDATA);
2537    return Void();
2538}
2539
2540Return<void> RadioImpl::getModemActivityInfo(int32_t serial) {
2541#if VDBG
2542    RLOGD("getModemActivityInfo: serial %d", serial);
2543#endif
2544    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_ACTIVITY_INFO);
2545    return Void();
2546}
2547
2548Return<void> RadioImpl::setAllowedCarriers(int32_t serial, bool allAllowed,
2549                                           const CarrierRestrictions& carriers) {
2550#if VDBG
2551    RLOGD("setAllowedCarriers: serial %d", serial);
2552#endif
2553    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
2554            RIL_REQUEST_SET_CARRIER_RESTRICTIONS);
2555    if (pRI == NULL) {
2556        return Void();
2557    }
2558
2559    RIL_CarrierRestrictions cr = {};
2560    RIL_Carrier *allowedCarriers = NULL;
2561    RIL_Carrier *excludedCarriers = NULL;
2562
2563    cr.len_allowed_carriers = carriers.allowedCarriers.size();
2564    allowedCarriers = (RIL_Carrier *)calloc(cr.len_allowed_carriers, sizeof(RIL_Carrier));
2565    if (allowedCarriers == NULL) {
2566        RLOGE("setAllowedCarriers: Memory allocation failed for request %s",
2567                requestToString(pRI->pCI->requestNumber));
2568        sendErrorResponse(pRI, RIL_E_NO_MEMORY);
2569        return Void();
2570    }
2571    cr.allowed_carriers = allowedCarriers;
2572
2573    cr.len_excluded_carriers = carriers.excludedCarriers.size();
2574    excludedCarriers = (RIL_Carrier *)calloc(cr.len_excluded_carriers, sizeof(RIL_Carrier));
2575    if (excludedCarriers == NULL) {
2576        RLOGE("setAllowedCarriers: Memory allocation failed for request %s",
2577                requestToString(pRI->pCI->requestNumber));
2578        sendErrorResponse(pRI, RIL_E_NO_MEMORY);
2579#ifdef MEMSET_FREED
2580        memset(allowedCarriers, 0, cr.len_allowed_carriers * sizeof(RIL_Carrier));
2581#endif
2582        free(allowedCarriers);
2583        return Void();
2584    }
2585    cr.excluded_carriers = excludedCarriers;
2586
2587    for (int i = 0; i < cr.len_allowed_carriers; i++) {
2588        allowedCarriers[i].mcc = carriers.allowedCarriers[i].mcc.c_str();
2589        allowedCarriers[i].mnc = carriers.allowedCarriers[i].mnc.c_str();
2590        allowedCarriers[i].match_type = (RIL_CarrierMatchType) carriers.allowedCarriers[i].matchType;
2591        allowedCarriers[i].match_data = carriers.allowedCarriers[i].matchData.c_str();
2592    }
2593
2594    for (int i = 0; i < cr.len_excluded_carriers; i++) {
2595        excludedCarriers[i].mcc = carriers.excludedCarriers[i].mcc.c_str();
2596        excludedCarriers[i].mnc = carriers.excludedCarriers[i].mnc.c_str();
2597        excludedCarriers[i].match_type =
2598                (RIL_CarrierMatchType) carriers.excludedCarriers[i].matchType;
2599        excludedCarriers[i].match_data = carriers.excludedCarriers[i].matchData.c_str();
2600    }
2601
2602    CALL_ONREQUEST(pRI->pCI->requestNumber, &cr, sizeof(RIL_CarrierRestrictions), pRI, mSlotId);
2603
2604#ifdef MEMSET_FREED
2605    memset(allowedCarriers, 0, cr.len_allowed_carriers * sizeof(RIL_Carrier));
2606    memset(excludedCarriers, 0, cr.len_excluded_carriers * sizeof(RIL_Carrier));
2607#endif
2608    free(allowedCarriers);
2609    free(excludedCarriers);
2610    return Void();
2611}
2612
2613Return<void> RadioImpl::getAllowedCarriers(int32_t serial) {
2614#if VDBG
2615    RLOGD("getAllowedCarriers: serial %d", serial);
2616#endif
2617    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CARRIER_RESTRICTIONS);
2618    return Void();
2619}
2620
2621Return<void> RadioImpl::sendDeviceState(int32_t serial, DeviceStateType deviceStateType,
2622                                        bool state) {
2623#if VDBG
2624    RLOGD("sendDeviceState: serial %d", serial);
2625#endif
2626    if (s_vendorFunctions->version < 15) {
2627        if (deviceStateType ==  DeviceStateType::LOW_DATA_EXPECTED) {
2628            RLOGD("sendDeviceState: calling screen state %d", BOOL_TO_INT(!state));
2629            dispatchInts(serial, mSlotId, RIL_REQUEST_SCREEN_STATE, 1, BOOL_TO_INT(!state));
2630        } else {
2631            RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
2632                    RIL_REQUEST_SEND_DEVICE_STATE);
2633            sendErrorResponse(pRI, RIL_E_REQUEST_NOT_SUPPORTED);
2634        }
2635        return Void();
2636    }
2637    dispatchInts(serial, mSlotId, RIL_REQUEST_SEND_DEVICE_STATE, 2, (int) deviceStateType,
2638            BOOL_TO_INT(state));
2639    return Void();
2640}
2641
2642Return<void> RadioImpl::setIndicationFilter(int32_t serial, int32_t indicationFilter) {
2643#if VDBG
2644    RLOGD("setIndicationFilter: serial %d", serial);
2645#endif
2646    if (s_vendorFunctions->version < 15) {
2647        RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
2648                RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER);
2649        sendErrorResponse(pRI, RIL_E_REQUEST_NOT_SUPPORTED);
2650        return Void();
2651    }
2652    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, 1, indicationFilter);
2653    return Void();
2654}
2655
2656Return<void> RadioImpl::setSimCardPower(int32_t serial, bool powerUp) {
2657#if VDBG
2658    RLOGD("setSimCardPower: serial %d", serial);
2659#endif
2660    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_SIM_CARD_POWER, 1, BOOL_TO_INT(powerUp));
2661    return Void();
2662}
2663
2664Return<void> RadioImpl::responseAcknowledgement() {
2665    android::releaseWakeLock();
2666    return Void();
2667}
2668
2669Return<void> OemHookImpl::setResponseFunctions(
2670        const ::android::sp<IOemHookResponse>& oemHookResponseParam,
2671        const ::android::sp<IOemHookIndication>& oemHookIndicationParam) {
2672#if VDBG
2673    RLOGD("OemHookImpl::setResponseFunctions");
2674#endif
2675
2676    pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock(mSlotId);
2677    int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr);
2678    assert(ret == 0);
2679
2680    mOemHookResponse = oemHookResponseParam;
2681    mOemHookIndication = oemHookIndicationParam;
2682    mCounterOemHook[mSlotId]++;
2683
2684    ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
2685    assert(ret == 0);
2686
2687    return Void();
2688}
2689
2690Return<void> OemHookImpl::sendRequestRaw(int32_t serial, const hidl_vec<uint8_t>& data) {
2691#if VDBG
2692    RLOGD("OemHookImpl::sendRequestRaw: serial %d", serial);
2693#endif
2694    dispatchRaw(serial, mSlotId, RIL_REQUEST_OEM_HOOK_RAW, data);
2695    return Void();
2696}
2697
2698Return<void> OemHookImpl::sendRequestStrings(int32_t serial,
2699        const hidl_vec<hidl_string>& data) {
2700#if VDBG
2701    RLOGD("OemHookImpl::sendRequestStrings: serial %d", serial);
2702#endif
2703    dispatchStrings(serial, mSlotId, RIL_REQUEST_OEM_HOOK_STRINGS, data);
2704    return Void();
2705}
2706
2707/***************************************************************************************************
2708 * RESPONSE FUNCTIONS
2709 * Functions above are used for requests going from framework to vendor code. The ones below are
2710 * responses for those requests coming back from the vendor code.
2711 **************************************************************************************************/
2712
2713void radio::acknowledgeRequest(int slotId, int serial) {
2714    if (radioService[slotId]->mRadioResponse != NULL) {
2715        Return<void> retStatus = radioService[slotId]->mRadioResponse->acknowledgeRequest(serial);
2716        radioService[slotId]->checkReturnStatus(retStatus);
2717    } else {
2718        RLOGE("acknowledgeRequest: radioService[%d]->mRadioResponse == NULL", slotId);
2719    }
2720}
2721
2722void populateResponseInfo(RadioResponseInfo& responseInfo, int serial, int responseType,
2723                         RIL_Errno e) {
2724    responseInfo.serial = serial;
2725    switch (responseType) {
2726        case RESPONSE_SOLICITED:
2727            responseInfo.type = RadioResponseType::SOLICITED;
2728            break;
2729        case RESPONSE_SOLICITED_ACK_EXP:
2730            responseInfo.type = RadioResponseType::SOLICITED_ACK_EXP;
2731            break;
2732    }
2733    responseInfo.error = (RadioError) e;
2734}
2735
2736int responseIntOrEmpty(RadioResponseInfo& responseInfo, int serial, int responseType, RIL_Errno e,
2737               void *response, size_t responseLen) {
2738    populateResponseInfo(responseInfo, serial, responseType, e);
2739    int ret = -1;
2740
2741    if (response == NULL && responseLen == 0) {
2742        // Earlier RILs did not send a response for some cases although the interface
2743        // expected an integer as response. Do not return error if response is empty. Instead
2744        // Return -1 in those cases to maintain backward compatibility.
2745    } else if (response == NULL || responseLen != sizeof(int)) {
2746        RLOGE("responseIntOrEmpty: Invalid response");
2747        if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
2748    } else {
2749        int *p_int = (int *) response;
2750        ret = p_int[0];
2751    }
2752    return ret;
2753}
2754
2755int responseInt(RadioResponseInfo& responseInfo, int serial, int responseType, RIL_Errno e,
2756               void *response, size_t responseLen) {
2757    populateResponseInfo(responseInfo, serial, responseType, e);
2758    int ret = -1;
2759
2760    if (response == NULL || responseLen != sizeof(int)) {
2761        RLOGE("responseInt: Invalid response");
2762        if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
2763    } else {
2764        int *p_int = (int *) response;
2765        ret = p_int[0];
2766    }
2767    return ret;
2768}
2769
2770int radio::getIccCardStatusResponse(int slotId,
2771                                   int responseType, int serial, RIL_Errno e,
2772                                   void *response, size_t responseLen) {
2773    if (radioService[slotId]->mRadioResponse != NULL) {
2774        RadioResponseInfo responseInfo = {};
2775        populateResponseInfo(responseInfo, serial, responseType, e);
2776        CardStatus cardStatus = {};
2777        if (response == NULL || responseLen != sizeof(RIL_CardStatus_v6)) {
2778            RLOGE("getIccCardStatusResponse: Invalid response");
2779            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
2780        } else {
2781            RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
2782            cardStatus.cardState = (CardState) p_cur->card_state;
2783            cardStatus.universalPinState = (PinState) p_cur->universal_pin_state;
2784            cardStatus.gsmUmtsSubscriptionAppIndex = p_cur->gsm_umts_subscription_app_index;
2785            cardStatus.cdmaSubscriptionAppIndex = p_cur->cdma_subscription_app_index;
2786            cardStatus.imsSubscriptionAppIndex = p_cur->ims_subscription_app_index;
2787
2788            RIL_AppStatus *rilAppStatus = p_cur->applications;
2789            cardStatus.applications.resize(p_cur->num_applications);
2790            AppStatus *appStatus = cardStatus.applications.data();
2791#if VDBG
2792            RLOGD("getIccCardStatusResponse: num_applications %d", p_cur->num_applications);
2793#endif
2794            for (int i = 0; i < p_cur->num_applications; i++) {
2795                appStatus[i].appType = (AppType) rilAppStatus[i].app_type;
2796                appStatus[i].appState = (AppState) rilAppStatus[i].app_state;
2797                appStatus[i].persoSubstate = (PersoSubstate) rilAppStatus[i].perso_substate;
2798                appStatus[i].aidPtr = convertCharPtrToHidlString(rilAppStatus[i].aid_ptr);
2799                appStatus[i].appLabelPtr = convertCharPtrToHidlString(
2800                        rilAppStatus[i].app_label_ptr);
2801                appStatus[i].pin1Replaced = rilAppStatus[i].pin1_replaced;
2802                appStatus[i].pin1 = (PinState) rilAppStatus[i].pin1;
2803                appStatus[i].pin2 = (PinState) rilAppStatus[i].pin2;
2804            }
2805        }
2806
2807        Return<void> retStatus = radioService[slotId]->mRadioResponse->
2808                getIccCardStatusResponse(responseInfo, cardStatus);
2809        radioService[slotId]->checkReturnStatus(retStatus);
2810    } else {
2811        RLOGE("getIccCardStatusResponse: radioService[%d]->mRadioResponse == NULL", slotId);
2812    }
2813
2814    return 0;
2815}
2816
2817int radio::supplyIccPinForAppResponse(int slotId,
2818                                     int responseType, int serial, RIL_Errno e,
2819                                     void *response, size_t responseLen) {
2820#if VDBG
2821    RLOGD("supplyIccPinForAppResponse: serial %d", serial);
2822#endif
2823
2824    if (radioService[slotId]->mRadioResponse != NULL) {
2825        RadioResponseInfo responseInfo = {};
2826        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
2827        Return<void> retStatus = radioService[slotId]->mRadioResponse->
2828                supplyIccPinForAppResponse(responseInfo, ret);
2829        RLOGE("supplyIccPinForAppResponse: amit ret %d", ret);
2830        radioService[slotId]->checkReturnStatus(retStatus);
2831    } else {
2832        RLOGE("supplyIccPinForAppResponse: radioService[%d]->mRadioResponse == NULL",
2833                slotId);
2834    }
2835
2836    return 0;
2837}
2838
2839int radio::supplyIccPukForAppResponse(int slotId,
2840                                     int responseType, int serial, RIL_Errno e,
2841                                     void *response, size_t responseLen) {
2842#if VDBG
2843    RLOGD("supplyIccPukForAppResponse: serial %d", serial);
2844#endif
2845
2846    if (radioService[slotId]->mRadioResponse != NULL) {
2847        RadioResponseInfo responseInfo = {};
2848        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
2849        Return<void> retStatus = radioService[slotId]->mRadioResponse->supplyIccPukForAppResponse(
2850                responseInfo, ret);
2851        radioService[slotId]->checkReturnStatus(retStatus);
2852    } else {
2853        RLOGE("supplyIccPukForAppResponse: radioService[%d]->mRadioResponse == NULL",
2854                slotId);
2855    }
2856
2857    return 0;
2858}
2859
2860int radio::supplyIccPin2ForAppResponse(int slotId,
2861                                      int responseType, int serial, RIL_Errno e,
2862                                      void *response, size_t responseLen) {
2863#if VDBG
2864    RLOGD("supplyIccPin2ForAppResponse: serial %d", serial);
2865#endif
2866
2867    if (radioService[slotId]->mRadioResponse != NULL) {
2868        RadioResponseInfo responseInfo = {};
2869        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
2870        Return<void> retStatus = radioService[slotId]->mRadioResponse->
2871                supplyIccPin2ForAppResponse(responseInfo, ret);
2872        radioService[slotId]->checkReturnStatus(retStatus);
2873    } else {
2874        RLOGE("supplyIccPin2ForAppResponse: radioService[%d]->mRadioResponse == NULL",
2875                slotId);
2876    }
2877
2878    return 0;
2879}
2880
2881int radio::supplyIccPuk2ForAppResponse(int slotId,
2882                                      int responseType, int serial, RIL_Errno e,
2883                                      void *response, size_t responseLen) {
2884#if VDBG
2885    RLOGD("supplyIccPuk2ForAppResponse: serial %d", serial);
2886#endif
2887
2888    if (radioService[slotId]->mRadioResponse != NULL) {
2889        RadioResponseInfo responseInfo = {};
2890        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
2891        Return<void> retStatus = radioService[slotId]->mRadioResponse->
2892                supplyIccPuk2ForAppResponse(responseInfo, ret);
2893        radioService[slotId]->checkReturnStatus(retStatus);
2894    } else {
2895        RLOGE("supplyIccPuk2ForAppResponse: radioService[%d]->mRadioResponse == NULL",
2896                slotId);
2897    }
2898
2899    return 0;
2900}
2901
2902int radio::changeIccPinForAppResponse(int slotId,
2903                                     int responseType, int serial, RIL_Errno e,
2904                                     void *response, size_t responseLen) {
2905#if VDBG
2906    RLOGD("changeIccPinForAppResponse: serial %d", serial);
2907#endif
2908
2909    if (radioService[slotId]->mRadioResponse != NULL) {
2910        RadioResponseInfo responseInfo = {};
2911        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
2912        Return<void> retStatus = radioService[slotId]->mRadioResponse->
2913                changeIccPinForAppResponse(responseInfo, ret);
2914        radioService[slotId]->checkReturnStatus(retStatus);
2915    } else {
2916        RLOGE("changeIccPinForAppResponse: radioService[%d]->mRadioResponse == NULL",
2917                slotId);
2918    }
2919
2920    return 0;
2921}
2922
2923int radio::changeIccPin2ForAppResponse(int slotId,
2924                                      int responseType, int serial, RIL_Errno e,
2925                                      void *response, size_t responseLen) {
2926#if VDBG
2927    RLOGD("changeIccPin2ForAppResponse: serial %d", serial);
2928#endif
2929
2930    if (radioService[slotId]->mRadioResponse != NULL) {
2931        RadioResponseInfo responseInfo = {};
2932        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
2933        Return<void> retStatus = radioService[slotId]->mRadioResponse->
2934                changeIccPin2ForAppResponse(responseInfo, ret);
2935        radioService[slotId]->checkReturnStatus(retStatus);
2936    } else {
2937        RLOGE("changeIccPin2ForAppResponse: radioService[%d]->mRadioResponse == NULL",
2938                slotId);
2939    }
2940
2941    return 0;
2942}
2943
2944int radio::supplyNetworkDepersonalizationResponse(int slotId,
2945                                                 int responseType, int serial, RIL_Errno e,
2946                                                 void *response, size_t responseLen) {
2947#if VDBG
2948    RLOGD("supplyNetworkDepersonalizationResponse: serial %d", serial);
2949#endif
2950
2951    if (radioService[slotId]->mRadioResponse != NULL) {
2952        RadioResponseInfo responseInfo = {};
2953        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
2954        Return<void> retStatus = radioService[slotId]->mRadioResponse->
2955                supplyNetworkDepersonalizationResponse(responseInfo, ret);
2956        radioService[slotId]->checkReturnStatus(retStatus);
2957    } else {
2958        RLOGE("supplyNetworkDepersonalizationResponse: radioService[%d]->mRadioResponse == "
2959                "NULL", slotId);
2960    }
2961
2962    return 0;
2963}
2964
2965int radio::getCurrentCallsResponse(int slotId,
2966                                  int responseType, int serial, RIL_Errno e,
2967                                  void *response, size_t responseLen) {
2968#if VDBG
2969    RLOGD("getCurrentCallsResponse: serial %d", serial);
2970#endif
2971
2972    if (radioService[slotId]->mRadioResponse != NULL) {
2973        RadioResponseInfo responseInfo = {};
2974        populateResponseInfo(responseInfo, serial, responseType, e);
2975
2976        hidl_vec<Call> calls;
2977        if ((response == NULL && responseLen != 0)
2978                || (responseLen % sizeof(RIL_Call *)) != 0) {
2979            RLOGE("getCurrentCallsResponse: Invalid response");
2980            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
2981        } else {
2982            int num = responseLen / sizeof(RIL_Call *);
2983            calls.resize(num);
2984
2985            for (int i = 0 ; i < num ; i++) {
2986                RIL_Call *p_cur = ((RIL_Call **) response)[i];
2987                /* each call info */
2988                calls[i].state = (CallState) p_cur->state;
2989                calls[i].index = p_cur->index;
2990                calls[i].toa = p_cur->toa;
2991                calls[i].isMpty = p_cur->isMpty;
2992                calls[i].isMT = p_cur->isMT;
2993                calls[i].als = p_cur->als;
2994                calls[i].isVoice = p_cur->isVoice;
2995                calls[i].isVoicePrivacy = p_cur->isVoicePrivacy;
2996                calls[i].number = convertCharPtrToHidlString(p_cur->number);
2997                calls[i].numberPresentation = (CallPresentation) p_cur->numberPresentation;
2998                calls[i].name = convertCharPtrToHidlString(p_cur->name);
2999                calls[i].namePresentation = (CallPresentation) p_cur->namePresentation;
3000                if (p_cur->uusInfo != NULL && p_cur->uusInfo->uusData != NULL) {
3001                    RIL_UUS_Info *uusInfo = p_cur->uusInfo;
3002                    calls[i].uusInfo[0].uusType = (UusType) uusInfo->uusType;
3003                    calls[i].uusInfo[0].uusDcs = (UusDcs) uusInfo->uusDcs;
3004                    // convert uusInfo->uusData to a null-terminated string
3005                    char *nullTermStr = strndup(uusInfo->uusData, uusInfo->uusLength);
3006                    calls[i].uusInfo[0].uusData = nullTermStr;
3007                    free(nullTermStr);
3008                }
3009            }
3010        }
3011
3012        Return<void> retStatus = radioService[slotId]->mRadioResponse->
3013                getCurrentCallsResponse(responseInfo, calls);
3014        radioService[slotId]->checkReturnStatus(retStatus);
3015    } else {
3016        RLOGE("getCurrentCallsResponse: radioService[%d]->mRadioResponse == NULL", slotId);
3017    }
3018
3019    return 0;
3020}
3021
3022int radio::dialResponse(int slotId,
3023                       int responseType, int serial, RIL_Errno e, void *response,
3024                       size_t responseLen) {
3025#if VDBG
3026    RLOGD("dialResponse: serial %d", serial);
3027#endif
3028
3029    if (radioService[slotId]->mRadioResponse != NULL) {
3030        RadioResponseInfo responseInfo = {};
3031        populateResponseInfo(responseInfo, serial, responseType, e);
3032        Return<void> retStatus = radioService[slotId]->mRadioResponse->dialResponse(responseInfo);
3033        radioService[slotId]->checkReturnStatus(retStatus);
3034    } else {
3035        RLOGE("dialResponse: radioService[%d]->mRadioResponse == NULL", slotId);
3036    }
3037
3038    return 0;
3039}
3040
3041int radio::getIMSIForAppResponse(int slotId,
3042                                int responseType, int serial, RIL_Errno e, void *response,
3043                                size_t responseLen) {
3044#if VDBG
3045    RLOGD("getIMSIForAppResponse: serial %d", serial);
3046#endif
3047
3048    if (radioService[slotId]->mRadioResponse != NULL) {
3049        RadioResponseInfo responseInfo = {};
3050        populateResponseInfo(responseInfo, serial, responseType, e);
3051        Return<void> retStatus = radioService[slotId]->mRadioResponse->getIMSIForAppResponse(
3052                responseInfo, convertCharPtrToHidlString((char *) response));
3053        radioService[slotId]->checkReturnStatus(retStatus);
3054    } else {
3055        RLOGE("getIMSIForAppResponse: radioService[%d]->mRadioResponse == NULL",
3056                slotId);
3057    }
3058
3059    return 0;
3060}
3061
3062int radio::hangupConnectionResponse(int slotId,
3063                                   int responseType, int serial, RIL_Errno e,
3064                                   void *response, size_t responseLen) {
3065#if VDBG
3066    RLOGD("hangupConnectionResponse: serial %d", serial);
3067#endif
3068
3069    if (radioService[slotId]->mRadioResponse != NULL) {
3070        RadioResponseInfo responseInfo = {};
3071        populateResponseInfo(responseInfo, serial, responseType, e);
3072        Return<void> retStatus = radioService[slotId]->mRadioResponse->hangupConnectionResponse(
3073                responseInfo);
3074        radioService[slotId]->checkReturnStatus(retStatus);
3075    } else {
3076        RLOGE("hangupConnectionResponse: radioService[%d]->mRadioResponse == NULL",
3077                slotId);
3078    }
3079
3080    return 0;
3081}
3082
3083int radio::hangupWaitingOrBackgroundResponse(int slotId,
3084                                            int responseType, int serial, RIL_Errno e,
3085                                            void *response, size_t responseLen) {
3086#if VDBG
3087    RLOGD("hangupWaitingOrBackgroundResponse: serial %d", serial);
3088#endif
3089
3090    if (radioService[slotId]->mRadioResponse != NULL) {
3091        RadioResponseInfo responseInfo = {};
3092        populateResponseInfo(responseInfo, serial, responseType, e);
3093        Return<void> retStatus =
3094                radioService[slotId]->mRadioResponse->hangupWaitingOrBackgroundResponse(
3095                responseInfo);
3096        radioService[slotId]->checkReturnStatus(retStatus);
3097    } else {
3098        RLOGE("hangupWaitingOrBackgroundResponse: radioService[%d]->mRadioResponse == NULL",
3099                slotId);
3100    }
3101
3102    return 0;
3103}
3104
3105int radio::hangupForegroundResumeBackgroundResponse(int slotId, int responseType, int serial,
3106                                                    RIL_Errno e, void *response,
3107                                                    size_t responseLen) {
3108#if VDBG
3109    RLOGD("hangupWaitingOrBackgroundResponse: serial %d", serial);
3110#endif
3111
3112    if (radioService[slotId]->mRadioResponse != NULL) {
3113        RadioResponseInfo responseInfo = {};
3114        populateResponseInfo(responseInfo, serial, responseType, e);
3115        Return<void> retStatus =
3116                radioService[slotId]->mRadioResponse->hangupWaitingOrBackgroundResponse(
3117                responseInfo);
3118        radioService[slotId]->checkReturnStatus(retStatus);
3119    } else {
3120        RLOGE("hangupWaitingOrBackgroundResponse: radioService[%d]->mRadioResponse == NULL",
3121                slotId);
3122    }
3123
3124    return 0;
3125}
3126
3127int radio::switchWaitingOrHoldingAndActiveResponse(int slotId, int responseType, int serial,
3128                                                   RIL_Errno e, void *response,
3129                                                   size_t responseLen) {
3130#if VDBG
3131    RLOGD("switchWaitingOrHoldingAndActiveResponse: serial %d", serial);
3132#endif
3133
3134    if (radioService[slotId]->mRadioResponse != NULL) {
3135        RadioResponseInfo responseInfo = {};
3136        populateResponseInfo(responseInfo, serial, responseType, e);
3137        Return<void> retStatus =
3138                radioService[slotId]->mRadioResponse->switchWaitingOrHoldingAndActiveResponse(
3139                responseInfo);
3140        radioService[slotId]->checkReturnStatus(retStatus);
3141    } else {
3142        RLOGE("switchWaitingOrHoldingAndActiveResponse: radioService[%d]->mRadioResponse "
3143                "== NULL", slotId);
3144    }
3145
3146    return 0;
3147}
3148
3149int radio::conferenceResponse(int slotId, int responseType,
3150                             int serial, RIL_Errno e, void *response, size_t responseLen) {
3151#if VDBG
3152    RLOGD("conferenceResponse: serial %d", serial);
3153#endif
3154
3155    if (radioService[slotId]->mRadioResponse != NULL) {
3156        RadioResponseInfo responseInfo = {};
3157        populateResponseInfo(responseInfo, serial, responseType, e);
3158        Return<void> retStatus = radioService[slotId]->mRadioResponse->conferenceResponse(
3159                responseInfo);
3160        radioService[slotId]->checkReturnStatus(retStatus);
3161    } else {
3162        RLOGE("conferenceResponse: radioService[%d]->mRadioResponse == NULL",
3163                slotId);
3164    }
3165
3166    return 0;
3167}
3168
3169int radio::rejectCallResponse(int slotId, int responseType,
3170                             int serial, RIL_Errno e, void *response, size_t responseLen) {
3171#if VDBG
3172    RLOGD("rejectCallResponse: serial %d", serial);
3173#endif
3174
3175    if (radioService[slotId]->mRadioResponse != NULL) {
3176        RadioResponseInfo responseInfo = {};
3177        populateResponseInfo(responseInfo, serial, responseType, e);
3178        Return<void> retStatus = radioService[slotId]->mRadioResponse->rejectCallResponse(
3179                responseInfo);
3180        radioService[slotId]->checkReturnStatus(retStatus);
3181    } else {
3182        RLOGE("rejectCallResponse: radioService[%d]->mRadioResponse == NULL",
3183                slotId);
3184    }
3185
3186    return 0;
3187}
3188
3189int radio::getLastCallFailCauseResponse(int slotId,
3190                                       int responseType, int serial, RIL_Errno e, void *response,
3191                                       size_t responseLen) {
3192#if VDBG
3193    RLOGD("getLastCallFailCauseResponse: serial %d", serial);
3194#endif
3195
3196    if (radioService[slotId]->mRadioResponse != NULL) {
3197        RadioResponseInfo responseInfo = {};
3198        populateResponseInfo(responseInfo, serial, responseType, e);
3199
3200        LastCallFailCauseInfo info = {};
3201        info.vendorCause = hidl_string();
3202        if (response == NULL) {
3203            RLOGE("getCurrentCallsResponse Invalid response: NULL");
3204            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
3205        } else if (responseLen == sizeof(int)) {
3206            int *pInt = (int *) response;
3207            info.causeCode = (LastCallFailCause) pInt[0];
3208        } else if (responseLen == sizeof(RIL_LastCallFailCauseInfo))  {
3209            RIL_LastCallFailCauseInfo *pFailCauseInfo = (RIL_LastCallFailCauseInfo *) response;
3210            info.causeCode = (LastCallFailCause) pFailCauseInfo->cause_code;
3211            info.vendorCause = convertCharPtrToHidlString(pFailCauseInfo->vendor_cause);
3212        } else {
3213            RLOGE("getCurrentCallsResponse Invalid response: NULL");
3214            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
3215        }
3216
3217        Return<void> retStatus = radioService[slotId]->mRadioResponse->getLastCallFailCauseResponse(
3218                responseInfo, info);
3219        radioService[slotId]->checkReturnStatus(retStatus);
3220    } else {
3221        RLOGE("getLastCallFailCauseResponse: radioService[%d]->mRadioResponse == NULL",
3222                slotId);
3223    }
3224
3225    return 0;
3226}
3227
3228int radio::getSignalStrengthResponse(int slotId,
3229                                     int responseType, int serial, RIL_Errno e,
3230                                     void *response, size_t responseLen) {
3231#if VDBG
3232    RLOGD("getSignalStrengthResponse: serial %d", serial);
3233#endif
3234
3235    if (radioService[slotId]->mRadioResponse != NULL) {
3236        RadioResponseInfo responseInfo = {};
3237        populateResponseInfo(responseInfo, serial, responseType, e);
3238        SignalStrength signalStrength = {};
3239        if (response == NULL || responseLen != sizeof(RIL_SignalStrength_v10)) {
3240            RLOGE("getSignalStrengthResponse: Invalid response");
3241            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
3242        } else {
3243            convertRilSignalStrengthToHal(response, responseLen, signalStrength);
3244        }
3245
3246        Return<void> retStatus = radioService[slotId]->mRadioResponse->getSignalStrengthResponse(
3247                responseInfo, signalStrength);
3248        radioService[slotId]->checkReturnStatus(retStatus);
3249    } else {
3250        RLOGE("getSignalStrengthResponse: radioService[%d]->mRadioResponse == NULL",
3251                slotId);
3252    }
3253
3254    return 0;
3255}
3256
3257RIL_CellInfoType getCellInfoTypeRadioTechnology(char *rat) {
3258    if (rat == NULL) {
3259        return RIL_CELL_INFO_TYPE_NONE;
3260    }
3261
3262    int radioTech = atoi(rat);
3263
3264    switch(radioTech) {
3265
3266        case RADIO_TECH_GPRS:
3267        case RADIO_TECH_EDGE:
3268        case RADIO_TECH_GSM: {
3269            return RIL_CELL_INFO_TYPE_GSM;
3270        }
3271
3272        case RADIO_TECH_UMTS:
3273        case RADIO_TECH_HSDPA:
3274        case RADIO_TECH_HSUPA:
3275        case RADIO_TECH_HSPA:
3276        case RADIO_TECH_HSPAP: {
3277            return RIL_CELL_INFO_TYPE_WCDMA;
3278        }
3279
3280        case RADIO_TECH_IS95A:
3281        case RADIO_TECH_IS95B:
3282        case RADIO_TECH_1xRTT:
3283        case RADIO_TECH_EVDO_0:
3284        case RADIO_TECH_EVDO_A:
3285        case RADIO_TECH_EVDO_B:
3286        case RADIO_TECH_EHRPD: {
3287            return RIL_CELL_INFO_TYPE_CDMA;
3288        }
3289
3290        case RADIO_TECH_LTE:
3291        case RADIO_TECH_LTE_CA: {
3292            return RIL_CELL_INFO_TYPE_LTE;
3293        }
3294
3295        case RADIO_TECH_TD_SCDMA: {
3296            return RIL_CELL_INFO_TYPE_TD_SCDMA;
3297        }
3298
3299        default: {
3300            break;
3301        }
3302    }
3303
3304    return RIL_CELL_INFO_TYPE_NONE;
3305
3306}
3307
3308void fillCellIdentityResponse(CellIdentity &cellIdentity, RIL_CellIdentity_v16 &rilCellIdentity) {
3309
3310    cellIdentity.cellIdentityGsm.resize(0);
3311    cellIdentity.cellIdentityWcdma.resize(0);
3312    cellIdentity.cellIdentityCdma.resize(0);
3313    cellIdentity.cellIdentityTdscdma.resize(0);
3314    cellIdentity.cellIdentityLte.resize(0);
3315    cellIdentity.cellInfoType = (CellInfoType)rilCellIdentity.cellInfoType;
3316    switch(rilCellIdentity.cellInfoType) {
3317
3318        case RIL_CELL_INFO_TYPE_GSM: {
3319            cellIdentity.cellIdentityGsm.resize(1);
3320            cellIdentity.cellIdentityGsm[0].mcc =
3321                    std::to_string(rilCellIdentity.cellIdentityGsm.mcc);
3322            cellIdentity.cellIdentityGsm[0].mnc =
3323                    std::to_string(rilCellIdentity.cellIdentityGsm.mnc);
3324            cellIdentity.cellIdentityGsm[0].lac = rilCellIdentity.cellIdentityGsm.lac;
3325            cellIdentity.cellIdentityGsm[0].cid = rilCellIdentity.cellIdentityGsm.cid;
3326            cellIdentity.cellIdentityGsm[0].arfcn = rilCellIdentity.cellIdentityGsm.arfcn;
3327            cellIdentity.cellIdentityGsm[0].bsic = rilCellIdentity.cellIdentityGsm.bsic;
3328            break;
3329        }
3330
3331        case RIL_CELL_INFO_TYPE_WCDMA: {
3332            cellIdentity.cellIdentityWcdma.resize(1);
3333            cellIdentity.cellIdentityWcdma[0].mcc =
3334                    std::to_string(rilCellIdentity.cellIdentityWcdma.mcc);
3335            cellIdentity.cellIdentityWcdma[0].mnc =
3336                    std::to_string(rilCellIdentity.cellIdentityWcdma.mnc);
3337            cellIdentity.cellIdentityWcdma[0].lac = rilCellIdentity.cellIdentityWcdma.lac;
3338            cellIdentity.cellIdentityWcdma[0].cid = rilCellIdentity.cellIdentityWcdma.cid;
3339            cellIdentity.cellIdentityWcdma[0].psc = rilCellIdentity.cellIdentityWcdma.psc;
3340            cellIdentity.cellIdentityWcdma[0].uarfcn = rilCellIdentity.cellIdentityWcdma.uarfcn;
3341            break;
3342        }
3343
3344        case RIL_CELL_INFO_TYPE_CDMA: {
3345            cellIdentity.cellIdentityCdma.resize(1);
3346            cellIdentity.cellIdentityCdma[0].networkId = rilCellIdentity.cellIdentityCdma.networkId;
3347            cellIdentity.cellIdentityCdma[0].systemId = rilCellIdentity.cellIdentityCdma.systemId;
3348            cellIdentity.cellIdentityCdma[0].baseStationId =
3349                    rilCellIdentity.cellIdentityCdma.basestationId;
3350            cellIdentity.cellIdentityCdma[0].longitude = rilCellIdentity.cellIdentityCdma.longitude;
3351            cellIdentity.cellIdentityCdma[0].latitude = rilCellIdentity.cellIdentityCdma.latitude;
3352            break;
3353        }
3354
3355        case RIL_CELL_INFO_TYPE_LTE: {
3356            cellIdentity.cellIdentityLte.resize(1);
3357            cellIdentity.cellIdentityLte[0].mcc =
3358                    std::to_string(rilCellIdentity.cellIdentityLte.mcc);
3359            cellIdentity.cellIdentityLte[0].mnc =
3360                    std::to_string(rilCellIdentity.cellIdentityLte.mnc);
3361            cellIdentity.cellIdentityLte[0].ci = rilCellIdentity.cellIdentityLte.ci;
3362            cellIdentity.cellIdentityLte[0].pci = rilCellIdentity.cellIdentityLte.pci;
3363            cellIdentity.cellIdentityLte[0].tac = rilCellIdentity.cellIdentityLte.tac;
3364            cellIdentity.cellIdentityLte[0].earfcn = rilCellIdentity.cellIdentityLte.earfcn;
3365            break;
3366        }
3367
3368        case RIL_CELL_INFO_TYPE_TD_SCDMA: {
3369            cellIdentity.cellIdentityTdscdma.resize(1);
3370            cellIdentity.cellIdentityTdscdma[0].mcc =
3371                    std::to_string(rilCellIdentity.cellIdentityTdscdma.mcc);
3372            cellIdentity.cellIdentityTdscdma[0].mnc =
3373                    std::to_string(rilCellIdentity.cellIdentityTdscdma.mnc);
3374            cellIdentity.cellIdentityTdscdma[0].lac = rilCellIdentity.cellIdentityTdscdma.lac;
3375            cellIdentity.cellIdentityTdscdma[0].cid = rilCellIdentity.cellIdentityTdscdma.cid;
3376            cellIdentity.cellIdentityTdscdma[0].cpid = rilCellIdentity.cellIdentityTdscdma.cpid;
3377            break;
3378        }
3379
3380        default: {
3381            break;
3382        }
3383    }
3384}
3385
3386int convertResponseStringEntryToInt(char **response, int index, int numStrings) {
3387    if ((response != NULL) &&  (numStrings > index) && (response[index] != NULL)) {
3388        return atoi(response[index]);
3389    }
3390
3391    return -1;
3392}
3393
3394int convertResponseHexStringEntryToInt(char **response, int index, int numStrings) {
3395    const int hexBase = 16;
3396    if ((response != NULL) &&  (numStrings > index) && (response[index] != NULL)) {
3397        return strtol(response[index], NULL, hexBase);
3398    }
3399
3400    return -1;
3401}
3402
3403/* Fill Cell Identity info from Voice Registration State Response.
3404 * This fucntion is applicable only for RIL Version < 15.
3405 * Response is a  "char **".
3406 * First and Second entries are in hex string format
3407 * and rest are integers represented in ascii format. */
3408void fillCellIdentityFromVoiceRegStateResponseString(CellIdentity &cellIdentity,
3409        int numStrings, char** response) {
3410
3411    RIL_CellIdentity_v16 rilCellIdentity;
3412    memset(&rilCellIdentity, -1, sizeof(RIL_CellIdentity_v16));
3413
3414    rilCellIdentity.cellInfoType = getCellInfoTypeRadioTechnology(response[3]);
3415    switch(rilCellIdentity.cellInfoType) {
3416
3417        case RIL_CELL_INFO_TYPE_GSM: {
3418            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
3419            rilCellIdentity.cellIdentityGsm.lac =
3420                    convertResponseHexStringEntryToInt(response, 1, numStrings);
3421
3422            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
3423            rilCellIdentity.cellIdentityGsm.cid =
3424                    convertResponseHexStringEntryToInt(response, 2, numStrings);
3425            break;
3426        }
3427
3428        case RIL_CELL_INFO_TYPE_WCDMA: {
3429            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
3430            rilCellIdentity.cellIdentityWcdma.lac =
3431                    convertResponseHexStringEntryToInt(response, 1, numStrings);
3432
3433            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
3434            rilCellIdentity.cellIdentityWcdma.cid =
3435                    convertResponseHexStringEntryToInt(response, 2, numStrings);
3436            rilCellIdentity.cellIdentityWcdma.psc =
3437                    convertResponseStringEntryToInt(response, 14, numStrings);
3438            break;
3439        }
3440
3441        case RIL_CELL_INFO_TYPE_TD_SCDMA:{
3442            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
3443            rilCellIdentity.cellIdentityTdscdma.lac =
3444                    convertResponseHexStringEntryToInt(response, 1, numStrings);
3445
3446            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
3447            rilCellIdentity.cellIdentityTdscdma.cid =
3448                    convertResponseHexStringEntryToInt(response, 2, numStrings);
3449            break;
3450        }
3451
3452        case RIL_CELL_INFO_TYPE_CDMA:{
3453            rilCellIdentity.cellIdentityCdma.basestationId =
3454                    convertResponseStringEntryToInt(response, 4, numStrings);
3455            rilCellIdentity.cellIdentityCdma.longitude =
3456                    convertResponseStringEntryToInt(response, 5, numStrings);
3457            rilCellIdentity.cellIdentityCdma.latitude =
3458                    convertResponseStringEntryToInt(response, 6, numStrings);
3459            rilCellIdentity.cellIdentityCdma.systemId =
3460                    convertResponseStringEntryToInt(response, 8, numStrings);
3461            rilCellIdentity.cellIdentityCdma.networkId =
3462                    convertResponseStringEntryToInt(response, 9, numStrings);
3463            break;
3464        }
3465
3466        case RIL_CELL_INFO_TYPE_LTE:{
3467            /* valid TAC are hexstrings in the range 0x0000 - 0xffff */
3468            rilCellIdentity.cellIdentityLte.tac =
3469                    convertResponseHexStringEntryToInt(response, 1, numStrings);
3470
3471            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
3472            rilCellIdentity.cellIdentityLte.ci =
3473                    convertResponseHexStringEntryToInt(response, 2, numStrings);
3474            break;
3475        }
3476
3477        default: {
3478            break;
3479        }
3480    }
3481
3482    fillCellIdentityResponse(cellIdentity, rilCellIdentity);
3483}
3484
3485/* Fill Cell Identity info from Data Registration State Response.
3486 * This fucntion is applicable only for RIL Version < 15.
3487 * Response is a  "char **".
3488 * First and Second entries are in hex string format
3489 * and rest are integers represented in ascii format. */
3490void fillCellIdentityFromDataRegStateResponseString(CellIdentity &cellIdentity,
3491        int numStrings, char** response) {
3492
3493    RIL_CellIdentity_v16 rilCellIdentity;
3494    memset(&rilCellIdentity, -1, sizeof(RIL_CellIdentity_v16));
3495
3496    rilCellIdentity.cellInfoType = getCellInfoTypeRadioTechnology(response[3]);
3497    switch(rilCellIdentity.cellInfoType) {
3498        case RIL_CELL_INFO_TYPE_GSM: {
3499            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
3500            rilCellIdentity.cellIdentityGsm.lac =
3501                    convertResponseHexStringEntryToInt(response, 1, numStrings);
3502
3503            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
3504            rilCellIdentity.cellIdentityGsm.cid =
3505                    convertResponseHexStringEntryToInt(response, 2, numStrings);
3506            break;
3507        }
3508        case RIL_CELL_INFO_TYPE_WCDMA: {
3509            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
3510            rilCellIdentity.cellIdentityWcdma.lac =
3511                    convertResponseHexStringEntryToInt(response, 1, numStrings);
3512
3513            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
3514            rilCellIdentity.cellIdentityWcdma.cid =
3515                    convertResponseHexStringEntryToInt(response, 2, numStrings);
3516            break;
3517        }
3518        case RIL_CELL_INFO_TYPE_TD_SCDMA:{
3519            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
3520            rilCellIdentity.cellIdentityTdscdma.lac =
3521                    convertResponseHexStringEntryToInt(response, 1, numStrings);
3522
3523            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
3524            rilCellIdentity.cellIdentityTdscdma.cid =
3525                    convertResponseHexStringEntryToInt(response, 2, numStrings);
3526            break;
3527        }
3528        case RIL_CELL_INFO_TYPE_LTE: {
3529            rilCellIdentity.cellIdentityLte.tac =
3530                    convertResponseStringEntryToInt(response, 6, numStrings);
3531            rilCellIdentity.cellIdentityLte.pci =
3532                    convertResponseStringEntryToInt(response, 7, numStrings);
3533            rilCellIdentity.cellIdentityLte.ci =
3534                    convertResponseStringEntryToInt(response, 8, numStrings);
3535            break;
3536        }
3537        default: {
3538            break;
3539        }
3540    }
3541
3542    fillCellIdentityResponse(cellIdentity, rilCellIdentity);
3543}
3544
3545int radio::getVoiceRegistrationStateResponse(int slotId,
3546                                            int responseType, int serial, RIL_Errno e,
3547                                            void *response, size_t responseLen) {
3548#if VDBG
3549    RLOGD("getVoiceRegistrationStateResponse: serial %d", serial);
3550#endif
3551
3552    if (radioService[slotId]->mRadioResponse != NULL) {
3553        RadioResponseInfo responseInfo = {};
3554        populateResponseInfo(responseInfo, serial, responseType, e);
3555
3556        VoiceRegStateResult voiceRegResponse = {};
3557        int numStrings = responseLen / sizeof(char *);
3558        if (response == NULL) {
3559               RLOGE("getVoiceRegistrationStateResponse Invalid response: NULL");
3560               if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
3561        } else if (s_vendorFunctions->version <= 14) {
3562            if (numStrings != 15) {
3563                RLOGE("getVoiceRegistrationStateResponse Invalid response: NULL");
3564                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
3565            } else {
3566                char **resp = (char **) response;
3567                voiceRegResponse.regState = (RegState) ATOI_NULL_HANDLED_DEF(resp[0], 4);
3568                voiceRegResponse.rat = ATOI_NULL_HANDLED(resp[3]);
3569                voiceRegResponse.cssSupported = ATOI_NULL_HANDLED_DEF(resp[7], 0);
3570                voiceRegResponse.roamingIndicator = ATOI_NULL_HANDLED(resp[10]);
3571                voiceRegResponse.systemIsInPrl = ATOI_NULL_HANDLED_DEF(resp[11], 0);
3572                voiceRegResponse.defaultRoamingIndicator = ATOI_NULL_HANDLED_DEF(resp[12], 0);
3573                voiceRegResponse.reasonForDenial = ATOI_NULL_HANDLED_DEF(resp[13], 0);
3574                fillCellIdentityFromVoiceRegStateResponseString(voiceRegResponse.cellIdentity,
3575                        numStrings, resp);
3576            }
3577        } else {
3578            RIL_VoiceRegistrationStateResponse *voiceRegState =
3579                    (RIL_VoiceRegistrationStateResponse *)response;
3580
3581            if (responseLen != sizeof(RIL_VoiceRegistrationStateResponse)) {
3582                RLOGE("getVoiceRegistrationStateResponse Invalid response: NULL");
3583                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
3584            } else {
3585                voiceRegResponse.regState = (RegState) voiceRegState->regState;
3586                voiceRegResponse.rat = voiceRegState->rat;;
3587                voiceRegResponse.cssSupported = voiceRegState->cssSupported;
3588                voiceRegResponse.roamingIndicator = voiceRegState->roamingIndicator;
3589                voiceRegResponse.systemIsInPrl = voiceRegState->systemIsInPrl;
3590                voiceRegResponse.defaultRoamingIndicator = voiceRegState->defaultRoamingIndicator;
3591                voiceRegResponse.reasonForDenial = voiceRegState->reasonForDenial;
3592                fillCellIdentityResponse(voiceRegResponse.cellIdentity,
3593                        voiceRegState->cellIdentity);
3594            }
3595        }
3596
3597        Return<void> retStatus =
3598                radioService[slotId]->mRadioResponse->getVoiceRegistrationStateResponse(
3599                responseInfo, voiceRegResponse);
3600        radioService[slotId]->checkReturnStatus(retStatus);
3601    } else {
3602        RLOGE("getVoiceRegistrationStateResponse: radioService[%d]->mRadioResponse == NULL",
3603                slotId);
3604    }
3605
3606    return 0;
3607}
3608
3609int radio::getDataRegistrationStateResponse(int slotId,
3610                                           int responseType, int serial, RIL_Errno e,
3611                                           void *response, size_t responseLen) {
3612#if VDBG
3613    RLOGD("getDataRegistrationStateResponse: serial %d", serial);
3614#endif
3615
3616    if (radioService[slotId]->mRadioResponse != NULL) {
3617        RadioResponseInfo responseInfo = {};
3618        populateResponseInfo(responseInfo, serial, responseType, e);
3619        DataRegStateResult dataRegResponse = {};
3620        if (response == NULL) {
3621            RLOGE("getDataRegistrationStateResponse Invalid response: NULL");
3622            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
3623        } else if (s_vendorFunctions->version <= 14) {
3624            int numStrings = responseLen / sizeof(char *);
3625            if ((numStrings != 6) && (numStrings != 11)) {
3626                RLOGE("getDataRegistrationStateResponse Invalid response: NULL");
3627                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
3628            } else {
3629                char **resp = (char **) response;
3630                dataRegResponse.regState = (RegState) ATOI_NULL_HANDLED_DEF(resp[0], 4);
3631                dataRegResponse.rat =  ATOI_NULL_HANDLED_DEF(resp[3], 0);
3632                dataRegResponse.reasonDataDenied =  ATOI_NULL_HANDLED(resp[4]);
3633                dataRegResponse.maxDataCalls =  ATOI_NULL_HANDLED_DEF(resp[5], 1);
3634                fillCellIdentityFromDataRegStateResponseString(dataRegResponse.cellIdentity,
3635                        numStrings, resp);
3636            }
3637        } else {
3638            RIL_DataRegistrationStateResponse *dataRegState =
3639                    (RIL_DataRegistrationStateResponse *)response;
3640
3641            if (responseLen != sizeof(RIL_DataRegistrationStateResponse)) {
3642                RLOGE("getDataRegistrationStateResponse Invalid response: NULL");
3643                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
3644            } else {
3645                dataRegResponse.regState = (RegState) dataRegState->regState;
3646                dataRegResponse.rat = dataRegState->rat;;
3647                dataRegResponse.reasonDataDenied = dataRegState->reasonDataDenied;
3648                dataRegResponse.maxDataCalls = dataRegState->maxDataCalls;
3649                fillCellIdentityResponse(dataRegResponse.cellIdentity, dataRegState->cellIdentity);
3650            }
3651        }
3652
3653        Return<void> retStatus =
3654                radioService[slotId]->mRadioResponse->getDataRegistrationStateResponse(responseInfo,
3655                dataRegResponse);
3656        radioService[slotId]->checkReturnStatus(retStatus);
3657    } else {
3658        RLOGE("getDataRegistrationStateResponse: radioService[%d]->mRadioResponse == NULL",
3659                slotId);
3660    }
3661
3662    return 0;
3663}
3664
3665int radio::getOperatorResponse(int slotId,
3666                              int responseType, int serial, RIL_Errno e, void *response,
3667                              size_t responseLen) {
3668#if VDBG
3669    RLOGD("getOperatorResponse: serial %d", serial);
3670#endif
3671
3672    if (radioService[slotId]->mRadioResponse != NULL) {
3673        RadioResponseInfo responseInfo = {};
3674        populateResponseInfo(responseInfo, serial, responseType, e);
3675        hidl_string longName;
3676        hidl_string shortName;
3677        hidl_string numeric;
3678        int numStrings = responseLen / sizeof(char *);
3679        if (response == NULL || numStrings != 3) {
3680            RLOGE("getOperatorResponse Invalid response: NULL");
3681            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
3682
3683        } else {
3684            char **resp = (char **) response;
3685            longName = convertCharPtrToHidlString(resp[0]);
3686            shortName = convertCharPtrToHidlString(resp[1]);
3687            numeric = convertCharPtrToHidlString(resp[2]);
3688        }
3689        Return<void> retStatus = radioService[slotId]->mRadioResponse->getOperatorResponse(
3690                responseInfo, longName, shortName, numeric);
3691        radioService[slotId]->checkReturnStatus(retStatus);
3692    } else {
3693        RLOGE("getOperatorResponse: radioService[%d]->mRadioResponse == NULL",
3694                slotId);
3695    }
3696
3697    return 0;
3698}
3699
3700int radio::setRadioPowerResponse(int slotId,
3701                                int responseType, int serial, RIL_Errno e, void *response,
3702                                size_t responseLen) {
3703    RLOGD("setRadioPowerResponse: serial %d", serial);
3704
3705    if (radioService[slotId]->mRadioResponse != NULL) {
3706        RadioResponseInfo responseInfo = {};
3707        populateResponseInfo(responseInfo, serial, responseType, e);
3708        Return<void> retStatus = radioService[slotId]->mRadioResponse->setRadioPowerResponse(
3709                responseInfo);
3710        radioService[slotId]->checkReturnStatus(retStatus);
3711    } else {
3712        RLOGE("setRadioPowerResponse: radioService[%d]->mRadioResponse == NULL",
3713                slotId);
3714    }
3715
3716    return 0;
3717}
3718
3719int radio::sendDtmfResponse(int slotId,
3720                           int responseType, int serial, RIL_Errno e, void *response,
3721                           size_t responseLen) {
3722#if VDBG
3723    RLOGD("sendDtmfResponse: serial %d", serial);
3724#endif
3725
3726    if (radioService[slotId]->mRadioResponse != NULL) {
3727        RadioResponseInfo responseInfo = {};
3728        populateResponseInfo(responseInfo, serial, responseType, e);
3729        Return<void> retStatus = radioService[slotId]->mRadioResponse->sendDtmfResponse(
3730                responseInfo);
3731        radioService[slotId]->checkReturnStatus(retStatus);
3732    } else {
3733        RLOGE("sendDtmfResponse: radioService[%d]->mRadioResponse == NULL",
3734                slotId);
3735    }
3736
3737    return 0;
3738}
3739
3740SendSmsResult makeSendSmsResult(RadioResponseInfo& responseInfo, int serial, int responseType,
3741                                RIL_Errno e, void *response, size_t responseLen) {
3742    populateResponseInfo(responseInfo, serial, responseType, e);
3743    SendSmsResult result = {};
3744
3745    if (response == NULL || responseLen != sizeof(RIL_SMS_Response)) {
3746        RLOGE("Invalid response: NULL");
3747        if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
3748        result.ackPDU = hidl_string();
3749    } else {
3750        RIL_SMS_Response *resp = (RIL_SMS_Response *) response;
3751        result.messageRef = resp->messageRef;
3752        result.ackPDU = convertCharPtrToHidlString(resp->ackPDU);
3753        result.errorCode = resp->errorCode;
3754    }
3755    return result;
3756}
3757
3758int radio::sendSmsResponse(int slotId,
3759                          int responseType, int serial, RIL_Errno e, void *response,
3760                          size_t responseLen) {
3761#if VDBG
3762    RLOGD("sendSmsResponse: serial %d", serial);
3763#endif
3764
3765    if (radioService[slotId]->mRadioResponse != NULL) {
3766        RadioResponseInfo responseInfo = {};
3767        SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response,
3768                responseLen);
3769
3770        Return<void> retStatus = radioService[slotId]->mRadioResponse->sendSmsResponse(responseInfo,
3771                result);
3772        radioService[slotId]->checkReturnStatus(retStatus);
3773    } else {
3774        RLOGE("sendSmsResponse: radioService[%d]->mRadioResponse == NULL", slotId);
3775    }
3776
3777    return 0;
3778}
3779
3780int radio::sendSMSExpectMoreResponse(int slotId,
3781                                    int responseType, int serial, RIL_Errno e, void *response,
3782                                    size_t responseLen) {
3783#if VDBG
3784    RLOGD("sendSMSExpectMoreResponse: serial %d", serial);
3785#endif
3786
3787    if (radioService[slotId]->mRadioResponse != NULL) {
3788        RadioResponseInfo responseInfo = {};
3789        SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response,
3790                responseLen);
3791
3792        Return<void> retStatus = radioService[slotId]->mRadioResponse->sendSMSExpectMoreResponse(
3793                responseInfo, result);
3794        radioService[slotId]->checkReturnStatus(retStatus);
3795    } else {
3796        RLOGE("sendSMSExpectMoreResponse: radioService[%d]->mRadioResponse == NULL", slotId);
3797    }
3798
3799    return 0;
3800}
3801
3802int radio::setupDataCallResponse(int slotId,
3803                                 int responseType, int serial, RIL_Errno e, void *response,
3804                                 size_t responseLen) {
3805#if VDBG
3806    RLOGD("setupDataCallResponse: serial %d", serial);
3807#endif
3808
3809    if (radioService[slotId]->mRadioResponse != NULL) {
3810        RadioResponseInfo responseInfo = {};
3811        populateResponseInfo(responseInfo, serial, responseType, e);
3812
3813        SetupDataCallResult result = {};
3814        if (response == NULL || (responseLen % sizeof(RIL_Data_Call_Response_v11)) != 0) {
3815            if (response != NULL) {
3816                RLOGE("setupDataCallResponse: Invalid response");
3817                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
3818            }
3819            result.status = DataCallFailCause::ERROR_UNSPECIFIED;
3820            result.type = hidl_string();
3821            result.ifname = hidl_string();
3822            result.addresses = hidl_string();
3823            result.dnses = hidl_string();
3824            result.gateways = hidl_string();
3825            result.pcscf = hidl_string();
3826        } else {
3827            convertRilDataCallToHal((RIL_Data_Call_Response_v11 *) response, result);
3828        }
3829
3830        Return<void> retStatus = radioService[slotId]->mRadioResponse->setupDataCallResponse(
3831                responseInfo, result);
3832        radioService[slotId]->checkReturnStatus(retStatus);
3833    } else {
3834        RLOGE("setupDataCallResponse: radioService[%d]->mRadioResponse == NULL", slotId);
3835    }
3836
3837    return 0;
3838}
3839
3840IccIoResult responseIccIo(RadioResponseInfo& responseInfo, int serial, int responseType,
3841                           RIL_Errno e, void *response, size_t responseLen) {
3842    populateResponseInfo(responseInfo, serial, responseType, e);
3843    IccIoResult result = {};
3844
3845    if (response == NULL || responseLen != sizeof(RIL_SIM_IO_Response)) {
3846        RLOGE("Invalid response: NULL");
3847        if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
3848        result.simResponse = hidl_string();
3849    } else {
3850        RIL_SIM_IO_Response *resp = (RIL_SIM_IO_Response *) response;
3851        result.sw1 = resp->sw1;
3852        result.sw2 = resp->sw2;
3853        result.simResponse = convertCharPtrToHidlString(resp->simResponse);
3854    }
3855    return result;
3856}
3857
3858int radio::iccIOForAppResponse(int slotId,
3859                      int responseType, int serial, RIL_Errno e, void *response,
3860                      size_t responseLen) {
3861#if VDBG
3862    RLOGD("iccIOForAppResponse: serial %d", serial);
3863#endif
3864
3865    if (radioService[slotId]->mRadioResponse != NULL) {
3866        RadioResponseInfo responseInfo = {};
3867        IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response,
3868                responseLen);
3869
3870        Return<void> retStatus = radioService[slotId]->mRadioResponse->iccIOForAppResponse(
3871                responseInfo, result);
3872        radioService[slotId]->checkReturnStatus(retStatus);
3873    } else {
3874        RLOGE("iccIOForAppResponse: radioService[%d]->mRadioResponse == NULL", slotId);
3875    }
3876
3877    return 0;
3878}
3879
3880int radio::sendUssdResponse(int slotId,
3881                           int responseType, int serial, RIL_Errno e, void *response,
3882                           size_t responseLen) {
3883#if VDBG
3884    RLOGD("sendUssdResponse: serial %d", serial);
3885#endif
3886
3887    if (radioService[slotId]->mRadioResponse != NULL) {
3888        RadioResponseInfo responseInfo = {};
3889        populateResponseInfo(responseInfo, serial, responseType, e);
3890        Return<void> retStatus = radioService[slotId]->mRadioResponse->sendUssdResponse(
3891                responseInfo);
3892        radioService[slotId]->checkReturnStatus(retStatus);
3893    } else {
3894        RLOGE("sendUssdResponse: radioService[%d]->mRadioResponse == NULL",
3895                slotId);
3896    }
3897
3898    return 0;
3899}
3900
3901int radio::cancelPendingUssdResponse(int slotId,
3902                                    int responseType, int serial, RIL_Errno e, void *response,
3903                                    size_t responseLen) {
3904#if VDBG
3905    RLOGD("cancelPendingUssdResponse: serial %d", serial);
3906#endif
3907
3908    if (radioService[slotId]->mRadioResponse != NULL) {
3909        RadioResponseInfo responseInfo = {};
3910        populateResponseInfo(responseInfo, serial, responseType, e);
3911        Return<void> retStatus = radioService[slotId]->mRadioResponse->cancelPendingUssdResponse(
3912                responseInfo);
3913        radioService[slotId]->checkReturnStatus(retStatus);
3914    } else {
3915        RLOGE("cancelPendingUssdResponse: radioService[%d]->mRadioResponse == NULL",
3916                slotId);
3917    }
3918
3919    return 0;
3920}
3921
3922int radio::getClirResponse(int slotId,
3923                              int responseType, int serial, RIL_Errno e, void *response,
3924                              size_t responseLen) {
3925#if VDBG
3926    RLOGD("getClirResponse: serial %d", serial);
3927#endif
3928
3929    if (radioService[slotId]->mRadioResponse != NULL) {
3930        RadioResponseInfo responseInfo = {};
3931        populateResponseInfo(responseInfo, serial, responseType, e);
3932        int n = -1, m = -1;
3933        int numInts = responseLen / sizeof(int);
3934        if (response == NULL || numInts != 2) {
3935            RLOGE("getClirResponse Invalid response: NULL");
3936            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
3937        } else {
3938            int *pInt = (int *) response;
3939            n = pInt[0];
3940            m = pInt[1];
3941        }
3942        Return<void> retStatus = radioService[slotId]->mRadioResponse->getClirResponse(responseInfo,
3943                n, m);
3944        radioService[slotId]->checkReturnStatus(retStatus);
3945    } else {
3946        RLOGE("getClirResponse: radioService[%d]->mRadioResponse == NULL", slotId);
3947    }
3948
3949    return 0;
3950}
3951
3952int radio::setClirResponse(int slotId,
3953                          int responseType, int serial, RIL_Errno e, void *response,
3954                          size_t responseLen) {
3955#if VDBG
3956    RLOGD("setClirResponse: serial %d", serial);
3957#endif
3958
3959    if (radioService[slotId]->mRadioResponse != NULL) {
3960        RadioResponseInfo responseInfo = {};
3961        populateResponseInfo(responseInfo, serial, responseType, e);
3962        Return<void> retStatus = radioService[slotId]->mRadioResponse->setClirResponse(
3963                responseInfo);
3964        radioService[slotId]->checkReturnStatus(retStatus);
3965    } else {
3966        RLOGE("setClirResponse: radioService[%d]->mRadioResponse == NULL", slotId);
3967    }
3968
3969    return 0;
3970}
3971
3972int radio::getCallForwardStatusResponse(int slotId,
3973                                       int responseType, int serial, RIL_Errno e,
3974                                       void *response, size_t responseLen) {
3975#if VDBG
3976    RLOGD("getCallForwardStatusResponse: serial %d", serial);
3977#endif
3978
3979    if (radioService[slotId]->mRadioResponse != NULL) {
3980        RadioResponseInfo responseInfo = {};
3981        populateResponseInfo(responseInfo, serial, responseType, e);
3982        hidl_vec<CallForwardInfo> callForwardInfos;
3983
3984        if ((response == NULL && responseLen != 0)
3985                || responseLen % sizeof(RIL_CallForwardInfo *) != 0) {
3986            RLOGE("getCallForwardStatusResponse Invalid response: NULL");
3987            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
3988        } else {
3989            int num = responseLen / sizeof(RIL_CallForwardInfo *);
3990            callForwardInfos.resize(num);
3991            for (int i = 0 ; i < num; i++) {
3992                RIL_CallForwardInfo *resp = ((RIL_CallForwardInfo **) response)[i];
3993                callForwardInfos[i].status = (CallForwardInfoStatus) resp->status;
3994                callForwardInfos[i].reason = resp->reason;
3995                callForwardInfos[i].serviceClass = resp->serviceClass;
3996                callForwardInfos[i].toa = resp->toa;
3997                callForwardInfos[i].number = convertCharPtrToHidlString(resp->number);
3998                callForwardInfos[i].timeSeconds = resp->timeSeconds;
3999            }
4000        }
4001
4002        Return<void> retStatus = radioService[slotId]->mRadioResponse->getCallForwardStatusResponse(
4003                responseInfo, callForwardInfos);
4004        radioService[slotId]->checkReturnStatus(retStatus);
4005    } else {
4006        RLOGE("getCallForwardStatusResponse: radioService[%d]->mRadioResponse == NULL",
4007                slotId);
4008    }
4009
4010    return 0;
4011}
4012
4013int radio::setCallForwardResponse(int slotId,
4014                                 int responseType, int serial, RIL_Errno e, void *response,
4015                                 size_t responseLen) {
4016#if VDBG
4017    RLOGD("setCallForwardResponse: serial %d", serial);
4018#endif
4019
4020    if (radioService[slotId]->mRadioResponse != NULL) {
4021        RadioResponseInfo responseInfo = {};
4022        populateResponseInfo(responseInfo, serial, responseType, e);
4023        Return<void> retStatus = radioService[slotId]->mRadioResponse->setCallForwardResponse(
4024                responseInfo);
4025        radioService[slotId]->checkReturnStatus(retStatus);
4026    } else {
4027        RLOGE("setCallForwardResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4028    }
4029
4030    return 0;
4031}
4032
4033int radio::getCallWaitingResponse(int slotId,
4034                                 int responseType, int serial, RIL_Errno e, void *response,
4035                                 size_t responseLen) {
4036#if VDBG
4037    RLOGD("getCallWaitingResponse: serial %d", serial);
4038#endif
4039
4040    if (radioService[slotId]->mRadioResponse != NULL) {
4041        RadioResponseInfo responseInfo = {};
4042        populateResponseInfo(responseInfo, serial, responseType, e);
4043        bool enable = false;
4044        int serviceClass = -1;
4045        int numInts = responseLen / sizeof(int);
4046        if (response == NULL || numInts != 2) {
4047            RLOGE("getCallWaitingResponse Invalid response: NULL");
4048            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
4049        } else {
4050            int *pInt = (int *) response;
4051            enable = pInt[0] == 1 ? true : false;
4052            serviceClass = pInt[1];
4053        }
4054        Return<void> retStatus = radioService[slotId]->mRadioResponse->getCallWaitingResponse(
4055                responseInfo, enable, serviceClass);
4056        radioService[slotId]->checkReturnStatus(retStatus);
4057    } else {
4058        RLOGE("getCallWaitingResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4059    }
4060
4061    return 0;
4062}
4063
4064int radio::setCallWaitingResponse(int slotId,
4065                                 int responseType, int serial, RIL_Errno e, void *response,
4066                                 size_t responseLen) {
4067#if VDBG
4068    RLOGD("setCallWaitingResponse: serial %d", serial);
4069#endif
4070
4071    if (radioService[slotId]->mRadioResponse != NULL) {
4072        RadioResponseInfo responseInfo = {};
4073        populateResponseInfo(responseInfo, serial, responseType, e);
4074        Return<void> retStatus = radioService[slotId]->mRadioResponse->setCallWaitingResponse(
4075                responseInfo);
4076        radioService[slotId]->checkReturnStatus(retStatus);
4077    } else {
4078        RLOGE("setCallWaitingResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4079    }
4080
4081    return 0;
4082}
4083
4084int radio::acknowledgeLastIncomingGsmSmsResponse(int slotId,
4085                                                int responseType, int serial, RIL_Errno e,
4086                                                void *response, size_t responseLen) {
4087#if VDBG
4088    RLOGD("acknowledgeLastIncomingGsmSmsResponse: serial %d", serial);
4089#endif
4090
4091    if (radioService[slotId]->mRadioResponse != NULL) {
4092        RadioResponseInfo responseInfo = {};
4093        populateResponseInfo(responseInfo, serial, responseType, e);
4094        Return<void> retStatus =
4095                radioService[slotId]->mRadioResponse->acknowledgeLastIncomingGsmSmsResponse(
4096                responseInfo);
4097        radioService[slotId]->checkReturnStatus(retStatus);
4098    } else {
4099        RLOGE("acknowledgeLastIncomingGsmSmsResponse: radioService[%d]->mRadioResponse "
4100                "== NULL", slotId);
4101    }
4102
4103    return 0;
4104}
4105
4106int radio::acceptCallResponse(int slotId,
4107                             int responseType, int serial, RIL_Errno e,
4108                             void *response, size_t responseLen) {
4109#if VDBG
4110    RLOGD("acceptCallResponse: serial %d", serial);
4111#endif
4112
4113    if (radioService[slotId]->mRadioResponse != NULL) {
4114        RadioResponseInfo responseInfo = {};
4115        populateResponseInfo(responseInfo, serial, responseType, e);
4116        Return<void> retStatus = radioService[slotId]->mRadioResponse->acceptCallResponse(
4117                responseInfo);
4118        radioService[slotId]->checkReturnStatus(retStatus);
4119    } else {
4120        RLOGE("acceptCallResponse: radioService[%d]->mRadioResponse == NULL",
4121                slotId);
4122    }
4123
4124    return 0;
4125}
4126
4127int radio::deactivateDataCallResponse(int slotId,
4128                                                int responseType, int serial, RIL_Errno e,
4129                                                void *response, size_t responseLen) {
4130#if VDBG
4131    RLOGD("deactivateDataCallResponse: serial %d", serial);
4132#endif
4133
4134    if (radioService[slotId]->mRadioResponse != NULL) {
4135        RadioResponseInfo responseInfo = {};
4136        populateResponseInfo(responseInfo, serial, responseType, e);
4137        Return<void> retStatus = radioService[slotId]->mRadioResponse->deactivateDataCallResponse(
4138                responseInfo);
4139        radioService[slotId]->checkReturnStatus(retStatus);
4140    } else {
4141        RLOGE("deactivateDataCallResponse: radioService[%d]->mRadioResponse == NULL",
4142                slotId);
4143    }
4144
4145    return 0;
4146}
4147
4148int radio::getFacilityLockForAppResponse(int slotId,
4149                                        int responseType, int serial, RIL_Errno e,
4150                                        void *response, size_t responseLen) {
4151#if VDBG
4152    RLOGD("getFacilityLockForAppResponse: serial %d", serial);
4153#endif
4154
4155    if (radioService[slotId]->mRadioResponse != NULL) {
4156        RadioResponseInfo responseInfo = {};
4157        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
4158        Return<void> retStatus = radioService[slotId]->mRadioResponse->
4159                getFacilityLockForAppResponse(responseInfo, ret);
4160        radioService[slotId]->checkReturnStatus(retStatus);
4161    } else {
4162        RLOGE("getFacilityLockForAppResponse: radioService[%d]->mRadioResponse == NULL",
4163                slotId);
4164    }
4165
4166    return 0;
4167}
4168
4169int radio::setFacilityLockForAppResponse(int slotId,
4170                                      int responseType, int serial, RIL_Errno e,
4171                                      void *response, size_t responseLen) {
4172#if VDBG
4173    RLOGD("setFacilityLockForAppResponse: serial %d", serial);
4174#endif
4175
4176    if (radioService[slotId]->mRadioResponse != NULL) {
4177        RadioResponseInfo responseInfo = {};
4178        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
4179        Return<void> retStatus
4180                = radioService[slotId]->mRadioResponse->setFacilityLockForAppResponse(responseInfo,
4181                ret);
4182        radioService[slotId]->checkReturnStatus(retStatus);
4183    } else {
4184        RLOGE("setFacilityLockForAppResponse: radioService[%d]->mRadioResponse == NULL",
4185                slotId);
4186    }
4187
4188    return 0;
4189}
4190
4191int radio::setBarringPasswordResponse(int slotId,
4192                             int responseType, int serial, RIL_Errno e,
4193                             void *response, size_t responseLen) {
4194#if VDBG
4195    RLOGD("acceptCallResponse: serial %d", serial);
4196#endif
4197
4198    if (radioService[slotId]->mRadioResponse != NULL) {
4199        RadioResponseInfo responseInfo = {};
4200        populateResponseInfo(responseInfo, serial, responseType, e);
4201        Return<void> retStatus
4202                = radioService[slotId]->mRadioResponse->setBarringPasswordResponse(responseInfo);
4203        radioService[slotId]->checkReturnStatus(retStatus);
4204    } else {
4205        RLOGE("setBarringPasswordResponse: radioService[%d]->mRadioResponse == NULL",
4206                slotId);
4207    }
4208
4209    return 0;
4210}
4211
4212int radio::getNetworkSelectionModeResponse(int slotId,
4213                                          int responseType, int serial, RIL_Errno e, void *response,
4214                                          size_t responseLen) {
4215#if VDBG
4216    RLOGD("getNetworkSelectionModeResponse: serial %d", serial);
4217#endif
4218
4219    if (radioService[slotId]->mRadioResponse != NULL) {
4220        RadioResponseInfo responseInfo = {};
4221        populateResponseInfo(responseInfo, serial, responseType, e);
4222        bool manual = false;
4223        int serviceClass;
4224        if (response == NULL || responseLen != sizeof(int)) {
4225            RLOGE("getNetworkSelectionModeResponse Invalid response: NULL");
4226            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
4227        } else {
4228            int *pInt = (int *) response;
4229            manual = pInt[0] == 1 ? true : false;
4230        }
4231        Return<void> retStatus
4232                = radioService[slotId]->mRadioResponse->getNetworkSelectionModeResponse(
4233                responseInfo,
4234                manual);
4235        radioService[slotId]->checkReturnStatus(retStatus);
4236    } else {
4237        RLOGE("getNetworkSelectionModeResponse: radioService[%d]->mRadioResponse == NULL",
4238                slotId);
4239    }
4240
4241    return 0;
4242}
4243
4244int radio::setNetworkSelectionModeAutomaticResponse(int slotId, int responseType, int serial,
4245                                                    RIL_Errno e, void *response,
4246                                                    size_t responseLen) {
4247#if VDBG
4248    RLOGD("setNetworkSelectionModeAutomaticResponse: serial %d", serial);
4249#endif
4250
4251    if (radioService[slotId]->mRadioResponse != NULL) {
4252        RadioResponseInfo responseInfo = {};
4253        populateResponseInfo(responseInfo, serial, responseType, e);
4254        Return<void> retStatus
4255                = radioService[slotId]->mRadioResponse->setNetworkSelectionModeAutomaticResponse(
4256                responseInfo);
4257        radioService[slotId]->checkReturnStatus(retStatus);
4258    } else {
4259        RLOGE("setNetworkSelectionModeAutomaticResponse: radioService[%d]->mRadioResponse "
4260                "== NULL", slotId);
4261    }
4262
4263    return 0;
4264}
4265
4266int radio::setNetworkSelectionModeManualResponse(int slotId,
4267                             int responseType, int serial, RIL_Errno e,
4268                             void *response, size_t responseLen) {
4269#if VDBG
4270    RLOGD("setNetworkSelectionModeManualResponse: serial %d", serial);
4271#endif
4272
4273    if (radioService[slotId]->mRadioResponse != NULL) {
4274        RadioResponseInfo responseInfo = {};
4275        populateResponseInfo(responseInfo, serial, responseType, e);
4276        Return<void> retStatus
4277                = radioService[slotId]->mRadioResponse->setNetworkSelectionModeManualResponse(
4278                responseInfo);
4279        radioService[slotId]->checkReturnStatus(retStatus);
4280    } else {
4281        RLOGE("acceptCallResponse: radioService[%d]->setNetworkSelectionModeManualResponse "
4282                "== NULL", slotId);
4283    }
4284
4285    return 0;
4286}
4287
4288int convertOperatorStatusToInt(const char *str) {
4289    if (strncmp("unknown", str, 9) == 0) {
4290        return (int) OperatorStatus::UNKNOWN;
4291    } else if (strncmp("available", str, 9) == 0) {
4292        return (int) OperatorStatus::AVAILABLE;
4293    } else if (strncmp("current", str, 9) == 0) {
4294        return (int) OperatorStatus::CURRENT;
4295    } else if (strncmp("forbidden", str, 9) == 0) {
4296        return (int) OperatorStatus::FORBIDDEN;
4297    } else {
4298        return -1;
4299    }
4300}
4301
4302int radio::getAvailableNetworksResponse(int slotId,
4303                              int responseType, int serial, RIL_Errno e, void *response,
4304                              size_t responseLen) {
4305#if VDBG
4306    RLOGD("getAvailableNetworksResponse: serial %d", serial);
4307#endif
4308
4309    if (radioService[slotId]->mRadioResponse != NULL) {
4310        RadioResponseInfo responseInfo = {};
4311        populateResponseInfo(responseInfo, serial, responseType, e);
4312        hidl_vec<OperatorInfo> networks;
4313        if ((response == NULL && responseLen != 0)
4314                || responseLen % (4 * sizeof(char *))!= 0) {
4315            RLOGE("getAvailableNetworksResponse Invalid response: NULL");
4316            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
4317        } else {
4318            char **resp = (char **) response;
4319            int numStrings = responseLen / sizeof(char *);
4320            networks.resize(numStrings/4);
4321            for (int i = 0, j = 0; i < numStrings; i = i + 4, j++) {
4322                networks[j].alphaLong = convertCharPtrToHidlString(resp[i]);
4323                networks[j].alphaShort = convertCharPtrToHidlString(resp[i + 1]);
4324                networks[j].operatorNumeric = convertCharPtrToHidlString(resp[i + 2]);
4325                int status = convertOperatorStatusToInt(resp[i + 3]);
4326                if (status == -1) {
4327                    if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
4328                } else {
4329                    networks[j].status = (OperatorStatus) status;
4330                }
4331            }
4332        }
4333        Return<void> retStatus
4334                = radioService[slotId]->mRadioResponse->getAvailableNetworksResponse(responseInfo,
4335                networks);
4336        radioService[slotId]->checkReturnStatus(retStatus);
4337    } else {
4338        RLOGE("getAvailableNetworksResponse: radioService[%d]->mRadioResponse == NULL",
4339                slotId);
4340    }
4341
4342    return 0;
4343}
4344
4345int radio::startDtmfResponse(int slotId,
4346                            int responseType, int serial, RIL_Errno e,
4347                            void *response, size_t responseLen) {
4348#if VDBG
4349    RLOGD("startDtmfResponse: serial %d", serial);
4350#endif
4351
4352    if (radioService[slotId]->mRadioResponse != NULL) {
4353        RadioResponseInfo responseInfo = {};
4354        populateResponseInfo(responseInfo, serial, responseType, e);
4355        Return<void> retStatus
4356                = radioService[slotId]->mRadioResponse->startDtmfResponse(responseInfo);
4357        radioService[slotId]->checkReturnStatus(retStatus);
4358    } else {
4359        RLOGE("startDtmfResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4360    }
4361
4362    return 0;
4363}
4364
4365int radio::stopDtmfResponse(int slotId,
4366                           int responseType, int serial, RIL_Errno e,
4367                           void *response, size_t responseLen) {
4368#if VDBG
4369    RLOGD("stopDtmfResponse: serial %d", serial);
4370#endif
4371
4372    if (radioService[slotId]->mRadioResponse != NULL) {
4373        RadioResponseInfo responseInfo = {};
4374        populateResponseInfo(responseInfo, serial, responseType, e);
4375        Return<void> retStatus
4376                = radioService[slotId]->mRadioResponse->stopDtmfResponse(responseInfo);
4377        radioService[slotId]->checkReturnStatus(retStatus);
4378    } else {
4379        RLOGE("stopDtmfResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4380    }
4381
4382    return 0;
4383}
4384
4385int radio::getBasebandVersionResponse(int slotId,
4386                                     int responseType, int serial, RIL_Errno e,
4387                                     void *response, size_t responseLen) {
4388#if VDBG
4389    RLOGD("getBasebandVersionResponse: serial %d", serial);
4390#endif
4391
4392    if (radioService[slotId]->mRadioResponse != NULL) {
4393        RadioResponseInfo responseInfo = {};
4394        populateResponseInfo(responseInfo, serial, responseType, e);
4395        Return<void> retStatus
4396                = radioService[slotId]->mRadioResponse->getBasebandVersionResponse(responseInfo,
4397                convertCharPtrToHidlString((char *) response));
4398        radioService[slotId]->checkReturnStatus(retStatus);
4399    } else {
4400        RLOGE("getBasebandVersionResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4401    }
4402
4403    return 0;
4404}
4405
4406int radio::separateConnectionResponse(int slotId,
4407                                     int responseType, int serial, RIL_Errno e,
4408                                     void *response, size_t responseLen) {
4409#if VDBG
4410    RLOGD("separateConnectionResponse: serial %d", serial);
4411#endif
4412
4413    if (radioService[slotId]->mRadioResponse != NULL) {
4414        RadioResponseInfo responseInfo = {};
4415        populateResponseInfo(responseInfo, serial, responseType, e);
4416        Return<void> retStatus
4417                = radioService[slotId]->mRadioResponse->separateConnectionResponse(responseInfo);
4418        radioService[slotId]->checkReturnStatus(retStatus);
4419    } else {
4420        RLOGE("separateConnectionResponse: radioService[%d]->mRadioResponse == NULL",
4421                slotId);
4422    }
4423
4424    return 0;
4425}
4426
4427int radio::setMuteResponse(int slotId,
4428                          int responseType, int serial, RIL_Errno e,
4429                          void *response, size_t responseLen) {
4430#if VDBG
4431    RLOGD("setMuteResponse: serial %d", serial);
4432#endif
4433
4434    if (radioService[slotId]->mRadioResponse != NULL) {
4435        RadioResponseInfo responseInfo = {};
4436        populateResponseInfo(responseInfo, serial, responseType, e);
4437        Return<void> retStatus
4438                = radioService[slotId]->mRadioResponse->setMuteResponse(responseInfo);
4439        radioService[slotId]->checkReturnStatus(retStatus);
4440    } else {
4441        RLOGE("setMuteResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4442    }
4443
4444    return 0;
4445}
4446
4447int radio::getMuteResponse(int slotId,
4448                          int responseType, int serial, RIL_Errno e, void *response,
4449                          size_t responseLen) {
4450#if VDBG
4451    RLOGD("getMuteResponse: serial %d", serial);
4452#endif
4453
4454    if (radioService[slotId]->mRadioResponse != NULL) {
4455        RadioResponseInfo responseInfo = {};
4456        populateResponseInfo(responseInfo, serial, responseType, e);
4457        bool enable = false;
4458        int serviceClass;
4459        if (response == NULL || responseLen != sizeof(int)) {
4460            RLOGE("getMuteResponse Invalid response: NULL");
4461            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
4462        } else {
4463            int *pInt = (int *) response;
4464            enable = pInt[0] == 1 ? true : false;
4465        }
4466        Return<void> retStatus = radioService[slotId]->mRadioResponse->getMuteResponse(responseInfo,
4467                enable);
4468        radioService[slotId]->checkReturnStatus(retStatus);
4469    } else {
4470        RLOGE("getMuteResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4471    }
4472
4473    return 0;
4474}
4475
4476int radio::getClipResponse(int slotId,
4477                          int responseType, int serial, RIL_Errno e,
4478                          void *response, size_t responseLen) {
4479#if VDBG
4480    RLOGD("getClipResponse: serial %d", serial);
4481#endif
4482
4483    if (radioService[slotId]->mRadioResponse != NULL) {
4484        RadioResponseInfo responseInfo = {};
4485        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
4486        Return<void> retStatus = radioService[slotId]->mRadioResponse->getClipResponse(responseInfo,
4487                (ClipStatus) ret);
4488        radioService[slotId]->checkReturnStatus(retStatus);
4489    } else {
4490        RLOGE("getClipResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4491    }
4492
4493    return 0;
4494}
4495
4496int radio::getDataCallListResponse(int slotId,
4497                                   int responseType, int serial, RIL_Errno e,
4498                                   void *response, size_t responseLen) {
4499#if VDBG
4500    RLOGD("getDataCallListResponse: serial %d", serial);
4501#endif
4502
4503    if (radioService[slotId]->mRadioResponse != NULL) {
4504        RadioResponseInfo responseInfo = {};
4505        populateResponseInfo(responseInfo, serial, responseType, e);
4506
4507        hidl_vec<SetupDataCallResult> ret;
4508        if ((response == NULL && responseLen != 0)
4509                || responseLen % sizeof(RIL_Data_Call_Response_v11) != 0) {
4510            RLOGE("getDataCallListResponse: invalid response");
4511            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
4512        } else {
4513            convertRilDataCallListToHal(response, responseLen, ret);
4514        }
4515
4516        Return<void> retStatus = radioService[slotId]->mRadioResponse->getDataCallListResponse(
4517                responseInfo, ret);
4518        radioService[slotId]->checkReturnStatus(retStatus);
4519    } else {
4520        RLOGE("getDataCallListResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4521    }
4522
4523    return 0;
4524}
4525
4526int radio::setSuppServiceNotificationsResponse(int slotId,
4527                                              int responseType, int serial, RIL_Errno e,
4528                                              void *response, size_t responseLen) {
4529#if VDBG
4530    RLOGD("setSuppServiceNotificationsResponse: serial %d", serial);
4531#endif
4532
4533    if (radioService[slotId]->mRadioResponse != NULL) {
4534        RadioResponseInfo responseInfo = {};
4535        populateResponseInfo(responseInfo, serial, responseType, e);
4536        Return<void> retStatus
4537                = radioService[slotId]->mRadioResponse->setSuppServiceNotificationsResponse(
4538                responseInfo);
4539        radioService[slotId]->checkReturnStatus(retStatus);
4540    } else {
4541        RLOGE("setSuppServiceNotificationsResponse: radioService[%d]->mRadioResponse "
4542                "== NULL", slotId);
4543    }
4544
4545    return 0;
4546}
4547
4548int radio::deleteSmsOnSimResponse(int slotId,
4549                                 int responseType, int serial, RIL_Errno e,
4550                                 void *response, size_t responseLen) {
4551#if VDBG
4552    RLOGD("deleteSmsOnSimResponse: serial %d", serial);
4553#endif
4554
4555    if (radioService[slotId]->mRadioResponse != NULL) {
4556        RadioResponseInfo responseInfo = {};
4557        populateResponseInfo(responseInfo, serial, responseType, e);
4558        Return<void> retStatus
4559                = radioService[slotId]->mRadioResponse->deleteSmsOnSimResponse(responseInfo);
4560        radioService[slotId]->checkReturnStatus(retStatus);
4561    } else {
4562        RLOGE("deleteSmsOnSimResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4563    }
4564
4565    return 0;
4566}
4567
4568int radio::setBandModeResponse(int slotId,
4569                              int responseType, int serial, RIL_Errno e,
4570                              void *response, size_t responseLen) {
4571#if VDBG
4572    RLOGD("setBandModeResponse: serial %d", serial);
4573#endif
4574
4575    if (radioService[slotId]->mRadioResponse != NULL) {
4576        RadioResponseInfo responseInfo = {};
4577        populateResponseInfo(responseInfo, serial, responseType, e);
4578        Return<void> retStatus
4579                = radioService[slotId]->mRadioResponse->setBandModeResponse(responseInfo);
4580        radioService[slotId]->checkReturnStatus(retStatus);
4581    } else {
4582        RLOGE("setBandModeResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4583    }
4584
4585    return 0;
4586}
4587
4588int radio::writeSmsToSimResponse(int slotId,
4589                                int responseType, int serial, RIL_Errno e,
4590                                void *response, size_t responseLen) {
4591#if VDBG
4592    RLOGD("writeSmsToSimResponse: serial %d", serial);
4593#endif
4594
4595    if (radioService[slotId]->mRadioResponse != NULL) {
4596        RadioResponseInfo responseInfo = {};
4597        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
4598        Return<void> retStatus
4599                = radioService[slotId]->mRadioResponse->writeSmsToSimResponse(responseInfo, ret);
4600        radioService[slotId]->checkReturnStatus(retStatus);
4601    } else {
4602        RLOGE("writeSmsToSimResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4603    }
4604
4605    return 0;
4606}
4607
4608int radio::getAvailableBandModesResponse(int slotId,
4609                                        int responseType, int serial, RIL_Errno e, void *response,
4610                                        size_t responseLen) {
4611#if VDBG
4612    RLOGD("getAvailableBandModesResponse: serial %d", serial);
4613#endif
4614
4615    if (radioService[slotId]->mRadioResponse != NULL) {
4616        RadioResponseInfo responseInfo = {};
4617        populateResponseInfo(responseInfo, serial, responseType, e);
4618        hidl_vec<RadioBandMode> modes;
4619        if ((response == NULL && responseLen != 0)|| responseLen % sizeof(int) != 0) {
4620            RLOGE("getAvailableBandModesResponse Invalid response: NULL");
4621            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
4622        } else {
4623            int *pInt = (int *) response;
4624            int numInts = responseLen / sizeof(int);
4625            modes.resize(numInts);
4626            for (int i = 0; i < numInts; i++) {
4627                modes[i] = (RadioBandMode) pInt[i];
4628            }
4629        }
4630        Return<void> retStatus
4631                = radioService[slotId]->mRadioResponse->getAvailableBandModesResponse(responseInfo,
4632                modes);
4633        radioService[slotId]->checkReturnStatus(retStatus);
4634    } else {
4635        RLOGE("getAvailableBandModesResponse: radioService[%d]->mRadioResponse == NULL",
4636                slotId);
4637    }
4638
4639    return 0;
4640}
4641
4642int radio::sendEnvelopeResponse(int slotId,
4643                               int responseType, int serial, RIL_Errno e,
4644                               void *response, size_t responseLen) {
4645#if VDBG
4646    RLOGD("sendEnvelopeResponse: serial %d", serial);
4647#endif
4648
4649    if (radioService[slotId]->mRadioResponse != NULL) {
4650        RadioResponseInfo responseInfo = {};
4651        populateResponseInfo(responseInfo, serial, responseType, e);
4652        Return<void> retStatus
4653                = radioService[slotId]->mRadioResponse->sendEnvelopeResponse(responseInfo,
4654                convertCharPtrToHidlString((char *) response));
4655        radioService[slotId]->checkReturnStatus(retStatus);
4656    } else {
4657        RLOGE("sendEnvelopeResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4658    }
4659
4660    return 0;
4661}
4662
4663int radio::sendTerminalResponseToSimResponse(int slotId,
4664                                            int responseType, int serial, RIL_Errno e,
4665                                            void *response, size_t responseLen) {
4666#if VDBG
4667    RLOGD("sendTerminalResponseToSimResponse: serial %d", serial);
4668#endif
4669
4670    if (radioService[slotId]->mRadioResponse != NULL) {
4671        RadioResponseInfo responseInfo = {};
4672        populateResponseInfo(responseInfo, serial, responseType, e);
4673        Return<void> retStatus
4674                = radioService[slotId]->mRadioResponse->sendTerminalResponseToSimResponse(
4675                responseInfo);
4676        radioService[slotId]->checkReturnStatus(retStatus);
4677    } else {
4678        RLOGE("sendTerminalResponseToSimResponse: radioService[%d]->mRadioResponse == NULL",
4679                slotId);
4680    }
4681
4682    return 0;
4683}
4684
4685int radio::handleStkCallSetupRequestFromSimResponse(int slotId,
4686                                                   int responseType, int serial,
4687                                                   RIL_Errno e, void *response,
4688                                                   size_t responseLen) {
4689#if VDBG
4690    RLOGD("handleStkCallSetupRequestFromSimResponse: serial %d", serial);
4691#endif
4692
4693    if (radioService[slotId]->mRadioResponse != NULL) {
4694        RadioResponseInfo responseInfo = {};
4695        populateResponseInfo(responseInfo, serial, responseType, e);
4696        Return<void> retStatus
4697                = radioService[slotId]->mRadioResponse->handleStkCallSetupRequestFromSimResponse(
4698                responseInfo);
4699        radioService[slotId]->checkReturnStatus(retStatus);
4700    } else {
4701        RLOGE("handleStkCallSetupRequestFromSimResponse: radioService[%d]->mRadioResponse "
4702                "== NULL", slotId);
4703    }
4704
4705    return 0;
4706}
4707
4708int radio::explicitCallTransferResponse(int slotId,
4709                                       int responseType, int serial, RIL_Errno e,
4710                                       void *response, size_t responseLen) {
4711#if VDBG
4712    RLOGD("explicitCallTransferResponse: serial %d", serial);
4713#endif
4714
4715    if (radioService[slotId]->mRadioResponse != NULL) {
4716        RadioResponseInfo responseInfo = {};
4717        populateResponseInfo(responseInfo, serial, responseType, e);
4718        Return<void> retStatus
4719                = radioService[slotId]->mRadioResponse->explicitCallTransferResponse(responseInfo);
4720        radioService[slotId]->checkReturnStatus(retStatus);
4721    } else {
4722        RLOGE("explicitCallTransferResponse: radioService[%d]->mRadioResponse == NULL",
4723                slotId);
4724    }
4725
4726    return 0;
4727}
4728
4729int radio::setPreferredNetworkTypeResponse(int slotId,
4730                                 int responseType, int serial, RIL_Errno e,
4731                                 void *response, size_t responseLen) {
4732#if VDBG
4733    RLOGD("setPreferredNetworkTypeResponse: serial %d", serial);
4734#endif
4735
4736    if (radioService[slotId]->mRadioResponse != NULL) {
4737        RadioResponseInfo responseInfo = {};
4738        populateResponseInfo(responseInfo, serial, responseType, e);
4739        Return<void> retStatus
4740                = radioService[slotId]->mRadioResponse->setPreferredNetworkTypeResponse(
4741                responseInfo);
4742        radioService[slotId]->checkReturnStatus(retStatus);
4743    } else {
4744        RLOGE("setPreferredNetworkTypeResponse: radioService[%d]->mRadioResponse == NULL",
4745                slotId);
4746    }
4747
4748    return 0;
4749}
4750
4751
4752int radio::getPreferredNetworkTypeResponse(int slotId,
4753                                          int responseType, int serial, RIL_Errno e,
4754                                          void *response, size_t responseLen) {
4755#if VDBG
4756    RLOGD("getPreferredNetworkTypeResponse: serial %d", serial);
4757#endif
4758
4759    if (radioService[slotId]->mRadioResponse != NULL) {
4760        RadioResponseInfo responseInfo = {};
4761        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
4762        Return<void> retStatus
4763                = radioService[slotId]->mRadioResponse->getPreferredNetworkTypeResponse(
4764                responseInfo, (PreferredNetworkType) ret);
4765        radioService[slotId]->checkReturnStatus(retStatus);
4766    } else {
4767        RLOGE("getPreferredNetworkTypeResponse: radioService[%d]->mRadioResponse == NULL",
4768                slotId);
4769    }
4770
4771    return 0;
4772}
4773
4774int radio::getNeighboringCidsResponse(int slotId,
4775                                     int responseType, int serial, RIL_Errno e,
4776                                     void *response, size_t responseLen) {
4777#if VDBG
4778    RLOGD("getNeighboringCidsResponse: serial %d", serial);
4779#endif
4780
4781    if (radioService[slotId]->mRadioResponse != NULL) {
4782        RadioResponseInfo responseInfo = {};
4783        populateResponseInfo(responseInfo, serial, responseType, e);
4784        hidl_vec<NeighboringCell> cells;
4785
4786        if ((response == NULL && responseLen != 0)
4787                || responseLen % sizeof(RIL_NeighboringCell *) != 0) {
4788            RLOGE("getNeighboringCidsResponse Invalid response: NULL");
4789            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
4790        } else {
4791            int num = responseLen / sizeof(RIL_NeighboringCell *);
4792            cells.resize(num);
4793            for (int i = 0 ; i < num; i++) {
4794                RIL_NeighboringCell *resp = ((RIL_NeighboringCell **) response)[i];
4795                cells[i].cid = convertCharPtrToHidlString(resp->cid);
4796                cells[i].rssi = resp->rssi;
4797            }
4798        }
4799
4800        Return<void> retStatus
4801                = radioService[slotId]->mRadioResponse->getNeighboringCidsResponse(responseInfo,
4802                cells);
4803        radioService[slotId]->checkReturnStatus(retStatus);
4804    } else {
4805        RLOGE("getNeighboringCidsResponse: radioService[%d]->mRadioResponse == NULL",
4806                slotId);
4807    }
4808
4809    return 0;
4810}
4811
4812int radio::setLocationUpdatesResponse(int slotId,
4813                                     int responseType, int serial, RIL_Errno e,
4814                                     void *response, size_t responseLen) {
4815#if VDBG
4816    RLOGD("setLocationUpdatesResponse: serial %d", serial);
4817#endif
4818
4819    if (radioService[slotId]->mRadioResponse != NULL) {
4820        RadioResponseInfo responseInfo = {};
4821        populateResponseInfo(responseInfo, serial, responseType, e);
4822        Return<void> retStatus
4823                = radioService[slotId]->mRadioResponse->setLocationUpdatesResponse(responseInfo);
4824        radioService[slotId]->checkReturnStatus(retStatus);
4825    } else {
4826        RLOGE("setLocationUpdatesResponse: radioService[%d]->mRadioResponse == NULL",
4827                slotId);
4828    }
4829
4830    return 0;
4831}
4832
4833int radio::setCdmaSubscriptionSourceResponse(int slotId,
4834                                 int responseType, int serial, RIL_Errno e,
4835                                 void *response, size_t responseLen) {
4836#if VDBG
4837    RLOGD("setCdmaSubscriptionSourceResponse: serial %d", serial);
4838#endif
4839
4840    if (radioService[slotId]->mRadioResponse != NULL) {
4841        RadioResponseInfo responseInfo = {};
4842        populateResponseInfo(responseInfo, serial, responseType, e);
4843        Return<void> retStatus
4844                = radioService[slotId]->mRadioResponse->setCdmaSubscriptionSourceResponse(
4845                responseInfo);
4846        radioService[slotId]->checkReturnStatus(retStatus);
4847    } else {
4848        RLOGE("setCdmaSubscriptionSourceResponse: radioService[%d]->mRadioResponse == NULL",
4849                slotId);
4850    }
4851
4852    return 0;
4853}
4854
4855int radio::setCdmaRoamingPreferenceResponse(int slotId,
4856                                 int responseType, int serial, RIL_Errno e,
4857                                 void *response, size_t responseLen) {
4858#if VDBG
4859    RLOGD("setCdmaRoamingPreferenceResponse: serial %d", serial);
4860#endif
4861
4862    if (radioService[slotId]->mRadioResponse != NULL) {
4863        RadioResponseInfo responseInfo = {};
4864        populateResponseInfo(responseInfo, serial, responseType, e);
4865        Return<void> retStatus
4866                = radioService[slotId]->mRadioResponse->setCdmaRoamingPreferenceResponse(
4867                responseInfo);
4868        radioService[slotId]->checkReturnStatus(retStatus);
4869    } else {
4870        RLOGE("setCdmaRoamingPreferenceResponse: radioService[%d]->mRadioResponse == NULL",
4871                slotId);
4872    }
4873
4874    return 0;
4875}
4876
4877int radio::getCdmaRoamingPreferenceResponse(int slotId,
4878                                           int responseType, int serial, RIL_Errno e,
4879                                           void *response, size_t responseLen) {
4880#if VDBG
4881    RLOGD("getCdmaRoamingPreferenceResponse: serial %d", serial);
4882#endif
4883
4884    if (radioService[slotId]->mRadioResponse != NULL) {
4885        RadioResponseInfo responseInfo = {};
4886        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
4887        Return<void> retStatus
4888                = radioService[slotId]->mRadioResponse->getCdmaRoamingPreferenceResponse(
4889                responseInfo, (CdmaRoamingType) ret);
4890        radioService[slotId]->checkReturnStatus(retStatus);
4891    } else {
4892        RLOGE("getCdmaRoamingPreferenceResponse: radioService[%d]->mRadioResponse == NULL",
4893                slotId);
4894    }
4895
4896    return 0;
4897}
4898
4899int radio::setTTYModeResponse(int slotId,
4900                             int responseType, int serial, RIL_Errno e,
4901                             void *response, size_t responseLen) {
4902#if VDBG
4903    RLOGD("setTTYModeResponse: serial %d", serial);
4904#endif
4905
4906    if (radioService[slotId]->mRadioResponse != NULL) {
4907        RadioResponseInfo responseInfo = {};
4908        populateResponseInfo(responseInfo, serial, responseType, e);
4909        Return<void> retStatus
4910                = radioService[slotId]->mRadioResponse->setTTYModeResponse(responseInfo);
4911        radioService[slotId]->checkReturnStatus(retStatus);
4912    } else {
4913        RLOGE("setTTYModeResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4914    }
4915
4916    return 0;
4917}
4918
4919int radio::getTTYModeResponse(int slotId,
4920                             int responseType, int serial, RIL_Errno e,
4921                             void *response, size_t responseLen) {
4922#if VDBG
4923    RLOGD("getTTYModeResponse: serial %d", serial);
4924#endif
4925
4926    if (radioService[slotId]->mRadioResponse != NULL) {
4927        RadioResponseInfo responseInfo = {};
4928        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
4929        Return<void> retStatus
4930                = radioService[slotId]->mRadioResponse->getTTYModeResponse(responseInfo,
4931                (TtyMode) ret);
4932        radioService[slotId]->checkReturnStatus(retStatus);
4933    } else {
4934        RLOGE("getTTYModeResponse: radioService[%d]->mRadioResponse == NULL", slotId);
4935    }
4936
4937    return 0;
4938}
4939
4940int radio::setPreferredVoicePrivacyResponse(int slotId,
4941                                 int responseType, int serial, RIL_Errno e,
4942                                 void *response, size_t responseLen) {
4943#if VDBG
4944    RLOGD("setPreferredVoicePrivacyResponse: serial %d", serial);
4945#endif
4946
4947    if (radioService[slotId]->mRadioResponse != NULL) {
4948        RadioResponseInfo responseInfo = {};
4949        populateResponseInfo(responseInfo, serial, responseType, e);
4950        Return<void> retStatus
4951                = radioService[slotId]->mRadioResponse->setPreferredVoicePrivacyResponse(
4952                responseInfo);
4953        radioService[slotId]->checkReturnStatus(retStatus);
4954    } else {
4955        RLOGE("setPreferredVoicePrivacyResponse: radioService[%d]->mRadioResponse == NULL",
4956                slotId);
4957    }
4958
4959    return 0;
4960}
4961
4962int radio::getPreferredVoicePrivacyResponse(int slotId,
4963                                           int responseType, int serial, RIL_Errno e,
4964                                           void *response, size_t responseLen) {
4965#if VDBG
4966    RLOGD("getPreferredVoicePrivacyResponse: serial %d", serial);
4967#endif
4968
4969    if (radioService[slotId]->mRadioResponse != NULL) {
4970        RadioResponseInfo responseInfo = {};
4971        populateResponseInfo(responseInfo, serial, responseType, e);
4972        bool enable = false;
4973        int numInts = responseLen / sizeof(int);
4974        if (response == NULL || numInts != 1) {
4975            RLOGE("getPreferredVoicePrivacyResponse Invalid response: NULL");
4976            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
4977        } else {
4978            int *pInt = (int *) response;
4979            enable = pInt[0] == 1 ? true : false;
4980        }
4981        Return<void> retStatus
4982                = radioService[slotId]->mRadioResponse->getPreferredVoicePrivacyResponse(
4983                responseInfo, enable);
4984        radioService[slotId]->checkReturnStatus(retStatus);
4985    } else {
4986        RLOGE("getPreferredVoicePrivacyResponse: radioService[%d]->mRadioResponse == NULL",
4987                slotId);
4988    }
4989
4990    return 0;
4991}
4992
4993int radio::sendCDMAFeatureCodeResponse(int slotId,
4994                                 int responseType, int serial, RIL_Errno e,
4995                                 void *response, size_t responseLen) {
4996#if VDBG
4997    RLOGD("sendCDMAFeatureCodeResponse: serial %d", serial);
4998#endif
4999
5000    if (radioService[slotId]->mRadioResponse != NULL) {
5001        RadioResponseInfo responseInfo = {};
5002        populateResponseInfo(responseInfo, serial, responseType, e);
5003        Return<void> retStatus
5004                = radioService[slotId]->mRadioResponse->sendCDMAFeatureCodeResponse(responseInfo);
5005        radioService[slotId]->checkReturnStatus(retStatus);
5006    } else {
5007        RLOGE("sendCDMAFeatureCodeResponse: radioService[%d]->mRadioResponse == NULL",
5008                slotId);
5009    }
5010
5011    return 0;
5012}
5013
5014int radio::sendBurstDtmfResponse(int slotId,
5015                                 int responseType, int serial, RIL_Errno e,
5016                                 void *response, size_t responseLen) {
5017#if VDBG
5018    RLOGD("sendBurstDtmfResponse: serial %d", serial);
5019#endif
5020
5021    if (radioService[slotId]->mRadioResponse != NULL) {
5022        RadioResponseInfo responseInfo = {};
5023        populateResponseInfo(responseInfo, serial, responseType, e);
5024        Return<void> retStatus
5025                = radioService[slotId]->mRadioResponse->sendBurstDtmfResponse(responseInfo);
5026        radioService[slotId]->checkReturnStatus(retStatus);
5027    } else {
5028        RLOGE("sendBurstDtmfResponse: radioService[%d]->mRadioResponse == NULL", slotId);
5029    }
5030
5031    return 0;
5032}
5033
5034int radio::sendCdmaSmsResponse(int slotId,
5035                              int responseType, int serial, RIL_Errno e, void *response,
5036                              size_t responseLen) {
5037#if VDBG
5038    RLOGD("sendCdmaSmsResponse: serial %d", serial);
5039#endif
5040
5041    if (radioService[slotId]->mRadioResponse != NULL) {
5042        RadioResponseInfo responseInfo = {};
5043        SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response,
5044                responseLen);
5045
5046        Return<void> retStatus
5047                = radioService[slotId]->mRadioResponse->sendCdmaSmsResponse(responseInfo, result);
5048        radioService[slotId]->checkReturnStatus(retStatus);
5049    } else {
5050        RLOGE("sendCdmaSmsResponse: radioService[%d]->mRadioResponse == NULL", slotId);
5051    }
5052
5053    return 0;
5054}
5055
5056int radio::acknowledgeLastIncomingCdmaSmsResponse(int slotId,
5057                                                 int responseType, int serial, RIL_Errno e,
5058                                                 void *response, size_t responseLen) {
5059#if VDBG
5060    RLOGD("acknowledgeLastIncomingCdmaSmsResponse: serial %d", serial);
5061#endif
5062
5063    if (radioService[slotId]->mRadioResponse != NULL) {
5064        RadioResponseInfo responseInfo = {};
5065        populateResponseInfo(responseInfo, serial, responseType, e);
5066        Return<void> retStatus
5067                = radioService[slotId]->mRadioResponse->acknowledgeLastIncomingCdmaSmsResponse(
5068                responseInfo);
5069        radioService[slotId]->checkReturnStatus(retStatus);
5070    } else {
5071        RLOGE("acknowledgeLastIncomingCdmaSmsResponse: radioService[%d]->mRadioResponse "
5072                "== NULL", slotId);
5073    }
5074
5075    return 0;
5076}
5077
5078int radio::getGsmBroadcastConfigResponse(int slotId,
5079                                        int responseType, int serial, RIL_Errno e,
5080                                        void *response, size_t responseLen) {
5081#if VDBG
5082    RLOGD("getGsmBroadcastConfigResponse: serial %d", serial);
5083#endif
5084
5085    if (radioService[slotId]->mRadioResponse != NULL) {
5086        RadioResponseInfo responseInfo = {};
5087        populateResponseInfo(responseInfo, serial, responseType, e);
5088        hidl_vec<GsmBroadcastSmsConfigInfo> configs;
5089
5090        if ((response == NULL && responseLen != 0)
5091                || responseLen % sizeof(RIL_GSM_BroadcastSmsConfigInfo *) != 0) {
5092            RLOGE("getGsmBroadcastConfigResponse Invalid response: NULL");
5093            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
5094        } else {
5095            int num = responseLen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *);
5096            configs.resize(num);
5097            for (int i = 0 ; i < num; i++) {
5098                RIL_GSM_BroadcastSmsConfigInfo *resp =
5099                        ((RIL_GSM_BroadcastSmsConfigInfo **) response)[i];
5100                configs[i].fromServiceId = resp->fromServiceId;
5101                configs[i].toServiceId = resp->toServiceId;
5102                configs[i].fromCodeScheme = resp->fromCodeScheme;
5103                configs[i].toCodeScheme = resp->toCodeScheme;
5104                configs[i].selected = resp->selected == 1 ? true : false;
5105            }
5106        }
5107
5108        Return<void> retStatus
5109                = radioService[slotId]->mRadioResponse->getGsmBroadcastConfigResponse(responseInfo,
5110                configs);
5111        radioService[slotId]->checkReturnStatus(retStatus);
5112    } else {
5113        RLOGE("getGsmBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL",
5114                slotId);
5115    }
5116
5117    return 0;
5118}
5119
5120int radio::setGsmBroadcastConfigResponse(int slotId,
5121                                        int responseType, int serial, RIL_Errno e,
5122                                        void *response, size_t responseLen) {
5123#if VDBG
5124    RLOGD("setGsmBroadcastConfigResponse: serial %d", serial);
5125#endif
5126
5127    if (radioService[slotId]->mRadioResponse != NULL) {
5128        RadioResponseInfo responseInfo = {};
5129        populateResponseInfo(responseInfo, serial, responseType, e);
5130        Return<void> retStatus
5131                = radioService[slotId]->mRadioResponse->setGsmBroadcastConfigResponse(responseInfo);
5132        radioService[slotId]->checkReturnStatus(retStatus);
5133    } else {
5134        RLOGE("setGsmBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL",
5135                slotId);
5136    }
5137
5138    return 0;
5139}
5140
5141int radio::setGsmBroadcastActivationResponse(int slotId,
5142                                            int responseType, int serial, RIL_Errno e,
5143                                            void *response, size_t responseLen) {
5144#if VDBG
5145    RLOGD("setGsmBroadcastActivationResponse: serial %d", serial);
5146#endif
5147
5148    if (radioService[slotId]->mRadioResponse != NULL) {
5149        RadioResponseInfo responseInfo = {};
5150        populateResponseInfo(responseInfo, serial, responseType, e);
5151        Return<void> retStatus
5152                = radioService[slotId]->mRadioResponse->setGsmBroadcastActivationResponse(
5153                responseInfo);
5154        radioService[slotId]->checkReturnStatus(retStatus);
5155    } else {
5156        RLOGE("setGsmBroadcastActivationResponse: radioService[%d]->mRadioResponse == NULL",
5157                slotId);
5158    }
5159
5160    return 0;
5161}
5162
5163int radio::getCdmaBroadcastConfigResponse(int slotId,
5164                                         int responseType, int serial, RIL_Errno e,
5165                                         void *response, size_t responseLen) {
5166#if VDBG
5167    RLOGD("getCdmaBroadcastConfigResponse: serial %d", serial);
5168#endif
5169
5170    if (radioService[slotId]->mRadioResponse != NULL) {
5171        RadioResponseInfo responseInfo = {};
5172        populateResponseInfo(responseInfo, serial, responseType, e);
5173        hidl_vec<CdmaBroadcastSmsConfigInfo> configs;
5174
5175        if ((response == NULL && responseLen != 0)
5176                || responseLen % sizeof(RIL_CDMA_BroadcastSmsConfigInfo *) != 0) {
5177            RLOGE("getCdmaBroadcastConfigResponse Invalid response: NULL");
5178            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
5179        } else {
5180            int num = responseLen / sizeof(RIL_CDMA_BroadcastSmsConfigInfo *);
5181            configs.resize(num);
5182            for (int i = 0 ; i < num; i++) {
5183                RIL_CDMA_BroadcastSmsConfigInfo *resp =
5184                        ((RIL_CDMA_BroadcastSmsConfigInfo **) response)[i];
5185                configs[i].serviceCategory = resp->service_category;
5186                configs[i].language = resp->language;
5187                configs[i].selected = resp->selected == 1 ? true : false;
5188            }
5189        }
5190
5191        Return<void> retStatus
5192                = radioService[slotId]->mRadioResponse->getCdmaBroadcastConfigResponse(responseInfo,
5193                configs);
5194        radioService[slotId]->checkReturnStatus(retStatus);
5195    } else {
5196        RLOGE("getCdmaBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL",
5197                slotId);
5198    }
5199
5200    return 0;
5201}
5202
5203int radio::setCdmaBroadcastConfigResponse(int slotId,
5204                                         int responseType, int serial, RIL_Errno e,
5205                                         void *response, size_t responseLen) {
5206#if VDBG
5207    RLOGD("setCdmaBroadcastConfigResponse: serial %d", serial);
5208#endif
5209
5210    if (radioService[slotId]->mRadioResponse != NULL) {
5211        RadioResponseInfo responseInfo = {};
5212        populateResponseInfo(responseInfo, serial, responseType, e);
5213        Return<void> retStatus
5214                = radioService[slotId]->mRadioResponse->setCdmaBroadcastConfigResponse(
5215                responseInfo);
5216        radioService[slotId]->checkReturnStatus(retStatus);
5217    } else {
5218        RLOGE("setCdmaBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL",
5219                slotId);
5220    }
5221
5222    return 0;
5223}
5224
5225int radio::setCdmaBroadcastActivationResponse(int slotId,
5226                                             int responseType, int serial, RIL_Errno e,
5227                                             void *response, size_t responseLen) {
5228#if VDBG
5229    RLOGD("setCdmaBroadcastActivationResponse: serial %d", serial);
5230#endif
5231
5232    if (radioService[slotId]->mRadioResponse != NULL) {
5233        RadioResponseInfo responseInfo = {};
5234        populateResponseInfo(responseInfo, serial, responseType, e);
5235        Return<void> retStatus
5236                = radioService[slotId]->mRadioResponse->setCdmaBroadcastActivationResponse(
5237                responseInfo);
5238        radioService[slotId]->checkReturnStatus(retStatus);
5239    } else {
5240        RLOGE("setCdmaBroadcastActivationResponse: radioService[%d]->mRadioResponse == NULL",
5241                slotId);
5242    }
5243
5244    return 0;
5245}
5246
5247int radio::getCDMASubscriptionResponse(int slotId,
5248                                      int responseType, int serial, RIL_Errno e, void *response,
5249                                      size_t responseLen) {
5250#if VDBG
5251    RLOGD("getCDMASubscriptionResponse: serial %d", serial);
5252#endif
5253
5254    if (radioService[slotId]->mRadioResponse != NULL) {
5255        RadioResponseInfo responseInfo = {};
5256        populateResponseInfo(responseInfo, serial, responseType, e);
5257
5258        int numStrings = responseLen / sizeof(char *);
5259        hidl_string emptyString;
5260        if (response == NULL || numStrings != 5) {
5261            RLOGE("getOperatorResponse Invalid response: NULL");
5262            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
5263            Return<void> retStatus
5264                    = radioService[slotId]->mRadioResponse->getCDMASubscriptionResponse(
5265                    responseInfo, emptyString, emptyString, emptyString, emptyString, emptyString);
5266            radioService[slotId]->checkReturnStatus(retStatus);
5267        } else {
5268            char **resp = (char **) response;
5269            Return<void> retStatus
5270                    = radioService[slotId]->mRadioResponse->getCDMASubscriptionResponse(
5271                    responseInfo,
5272                    convertCharPtrToHidlString(resp[0]),
5273                    convertCharPtrToHidlString(resp[1]),
5274                    convertCharPtrToHidlString(resp[2]),
5275                    convertCharPtrToHidlString(resp[3]),
5276                    convertCharPtrToHidlString(resp[4]));
5277            radioService[slotId]->checkReturnStatus(retStatus);
5278        }
5279    } else {
5280        RLOGE("getCDMASubscriptionResponse: radioService[%d]->mRadioResponse == NULL",
5281                slotId);
5282    }
5283
5284    return 0;
5285}
5286
5287int radio::writeSmsToRuimResponse(int slotId,
5288                                 int responseType, int serial, RIL_Errno e,
5289                                 void *response, size_t responseLen) {
5290#if VDBG
5291    RLOGD("writeSmsToRuimResponse: serial %d", serial);
5292#endif
5293
5294    if (radioService[slotId]->mRadioResponse != NULL) {
5295        RadioResponseInfo responseInfo = {};
5296        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
5297        Return<void> retStatus
5298                = radioService[slotId]->mRadioResponse->writeSmsToRuimResponse(responseInfo, ret);
5299        radioService[slotId]->checkReturnStatus(retStatus);
5300    } else {
5301        RLOGE("writeSmsToRuimResponse: radioService[%d]->mRadioResponse == NULL", slotId);
5302    }
5303
5304    return 0;
5305}
5306
5307int radio::deleteSmsOnRuimResponse(int slotId,
5308                                  int responseType, int serial, RIL_Errno e,
5309                                  void *response, size_t responseLen) {
5310#if VDBG
5311    RLOGD("deleteSmsOnRuimResponse: serial %d", serial);
5312#endif
5313
5314    if (radioService[slotId]->mRadioResponse != NULL) {
5315        RadioResponseInfo responseInfo = {};
5316        populateResponseInfo(responseInfo, serial, responseType, e);
5317        Return<void> retStatus
5318                = radioService[slotId]->mRadioResponse->deleteSmsOnRuimResponse(responseInfo);
5319        radioService[slotId]->checkReturnStatus(retStatus);
5320    } else {
5321        RLOGE("deleteSmsOnRuimResponse: radioService[%d]->mRadioResponse == NULL", slotId);
5322    }
5323
5324    return 0;
5325}
5326
5327int radio::getDeviceIdentityResponse(int slotId,
5328                                    int responseType, int serial, RIL_Errno e, void *response,
5329                                    size_t responseLen) {
5330#if VDBG
5331    RLOGD("getDeviceIdentityResponse: serial %d", serial);
5332#endif
5333
5334    if (radioService[slotId]->mRadioResponse != NULL) {
5335        RadioResponseInfo responseInfo = {};
5336        populateResponseInfo(responseInfo, serial, responseType, e);
5337
5338        int numStrings = responseLen / sizeof(char *);
5339        hidl_string emptyString;
5340        if (response == NULL || numStrings != 4) {
5341            RLOGE("getDeviceIdentityResponse Invalid response: NULL");
5342            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
5343            Return<void> retStatus
5344                    = radioService[slotId]->mRadioResponse->getDeviceIdentityResponse(responseInfo,
5345                    emptyString, emptyString, emptyString, emptyString);
5346            radioService[slotId]->checkReturnStatus(retStatus);
5347        } else {
5348            char **resp = (char **) response;
5349            Return<void> retStatus
5350                    = radioService[slotId]->mRadioResponse->getDeviceIdentityResponse(responseInfo,
5351                    convertCharPtrToHidlString(resp[0]),
5352                    convertCharPtrToHidlString(resp[1]),
5353                    convertCharPtrToHidlString(resp[2]),
5354                    convertCharPtrToHidlString(resp[3]));
5355            radioService[slotId]->checkReturnStatus(retStatus);
5356        }
5357    } else {
5358        RLOGE("getDeviceIdentityResponse: radioService[%d]->mRadioResponse == NULL",
5359                slotId);
5360    }
5361
5362    return 0;
5363}
5364
5365int radio::exitEmergencyCallbackModeResponse(int slotId,
5366                                            int responseType, int serial, RIL_Errno e,
5367                                            void *response, size_t responseLen) {
5368#if VDBG
5369    RLOGD("exitEmergencyCallbackModeResponse: serial %d", serial);
5370#endif
5371
5372    if (radioService[slotId]->mRadioResponse != NULL) {
5373        RadioResponseInfo responseInfo = {};
5374        populateResponseInfo(responseInfo, serial, responseType, e);
5375        Return<void> retStatus
5376                = radioService[slotId]->mRadioResponse->exitEmergencyCallbackModeResponse(
5377                responseInfo);
5378        radioService[slotId]->checkReturnStatus(retStatus);
5379    } else {
5380        RLOGE("exitEmergencyCallbackModeResponse: radioService[%d]->mRadioResponse == NULL",
5381                slotId);
5382    }
5383
5384    return 0;
5385}
5386
5387int radio::getSmscAddressResponse(int slotId,
5388                                  int responseType, int serial, RIL_Errno e,
5389                                  void *response, size_t responseLen) {
5390#if VDBG
5391    RLOGD("getSmscAddressResponse: serial %d", serial);
5392#endif
5393
5394    if (radioService[slotId]->mRadioResponse != NULL) {
5395        RadioResponseInfo responseInfo = {};
5396        populateResponseInfo(responseInfo, serial, responseType, e);
5397        Return<void> retStatus
5398                = radioService[slotId]->mRadioResponse->getSmscAddressResponse(responseInfo,
5399                convertCharPtrToHidlString((char *) response));
5400        radioService[slotId]->checkReturnStatus(retStatus);
5401    } else {
5402        RLOGE("getSmscAddressResponse: radioService[%d]->mRadioResponse == NULL", slotId);
5403    }
5404
5405    return 0;
5406}
5407
5408int radio::setSmscAddressResponse(int slotId,
5409                                             int responseType, int serial, RIL_Errno e,
5410                                             void *response, size_t responseLen) {
5411#if VDBG
5412    RLOGD("setSmscAddressResponse: serial %d", serial);
5413#endif
5414
5415    if (radioService[slotId]->mRadioResponse != NULL) {
5416        RadioResponseInfo responseInfo = {};
5417        populateResponseInfo(responseInfo, serial, responseType, e);
5418        Return<void> retStatus
5419                = radioService[slotId]->mRadioResponse->setSmscAddressResponse(responseInfo);
5420        radioService[slotId]->checkReturnStatus(retStatus);
5421    } else {
5422        RLOGE("setSmscAddressResponse: radioService[%d]->mRadioResponse == NULL", slotId);
5423    }
5424
5425    return 0;
5426}
5427
5428int radio::reportSmsMemoryStatusResponse(int slotId,
5429                                        int responseType, int serial, RIL_Errno e,
5430                                        void *response, size_t responseLen) {
5431#if VDBG
5432    RLOGD("reportSmsMemoryStatusResponse: serial %d", serial);
5433#endif
5434
5435    if (radioService[slotId]->mRadioResponse != NULL) {
5436        RadioResponseInfo responseInfo = {};
5437        populateResponseInfo(responseInfo, serial, responseType, e);
5438        Return<void> retStatus
5439                = radioService[slotId]->mRadioResponse->reportSmsMemoryStatusResponse(responseInfo);
5440        radioService[slotId]->checkReturnStatus(retStatus);
5441    } else {
5442        RLOGE("reportSmsMemoryStatusResponse: radioService[%d]->mRadioResponse == NULL",
5443                slotId);
5444    }
5445
5446    return 0;
5447}
5448
5449int radio::reportStkServiceIsRunningResponse(int slotId,
5450                                             int responseType, int serial, RIL_Errno e,
5451                                             void *response, size_t responseLen) {
5452#if VDBG
5453    RLOGD("reportStkServiceIsRunningResponse: serial %d", serial);
5454#endif
5455
5456    if (radioService[slotId]->mRadioResponse != NULL) {
5457        RadioResponseInfo responseInfo = {};
5458        populateResponseInfo(responseInfo, serial, responseType, e);
5459        Return<void> retStatus = radioService[slotId]->mRadioResponse->
5460                reportStkServiceIsRunningResponse(responseInfo);
5461        radioService[slotId]->checkReturnStatus(retStatus);
5462    } else {
5463        RLOGE("reportStkServiceIsRunningResponse: radioService[%d]->mRadioResponse == NULL",
5464                slotId);
5465    }
5466
5467    return 0;
5468}
5469
5470int radio::getCdmaSubscriptionSourceResponse(int slotId,
5471                                            int responseType, int serial, RIL_Errno e,
5472                                            void *response, size_t responseLen) {
5473#if VDBG
5474    RLOGD("getCdmaSubscriptionSourceResponse: serial %d", serial);
5475#endif
5476
5477    if (radioService[slotId]->mRadioResponse != NULL) {
5478        RadioResponseInfo responseInfo = {};
5479        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
5480        Return<void> retStatus
5481                = radioService[slotId]->mRadioResponse->getCdmaSubscriptionSourceResponse(
5482                responseInfo, (CdmaSubscriptionSource) ret);
5483        radioService[slotId]->checkReturnStatus(retStatus);
5484    } else {
5485        RLOGE("getCdmaSubscriptionSourceResponse: radioService[%d]->mRadioResponse == NULL",
5486                slotId);
5487    }
5488
5489    return 0;
5490}
5491
5492int radio::requestIsimAuthenticationResponse(int slotId,
5493                                            int responseType, int serial, RIL_Errno e,
5494                                            void *response, size_t responseLen) {
5495#if VDBG
5496    RLOGD("requestIsimAuthenticationResponse: serial %d", serial);
5497#endif
5498
5499    if (radioService[slotId]->mRadioResponse != NULL) {
5500        RadioResponseInfo responseInfo = {};
5501        populateResponseInfo(responseInfo, serial, responseType, e);
5502        Return<void> retStatus
5503                = radioService[slotId]->mRadioResponse->requestIsimAuthenticationResponse(
5504                responseInfo,
5505                convertCharPtrToHidlString((char *) response));
5506        radioService[slotId]->checkReturnStatus(retStatus);
5507    } else {
5508        RLOGE("requestIsimAuthenticationResponse: radioService[%d]->mRadioResponse == NULL",
5509                slotId);
5510    }
5511
5512    return 0;
5513}
5514
5515int radio::acknowledgeIncomingGsmSmsWithPduResponse(int slotId,
5516                                                   int responseType,
5517                                                   int serial, RIL_Errno e, void *response,
5518                                                   size_t responseLen) {
5519#if VDBG
5520    RLOGD("acknowledgeIncomingGsmSmsWithPduResponse: serial %d", serial);
5521#endif
5522
5523    if (radioService[slotId]->mRadioResponse != NULL) {
5524        RadioResponseInfo responseInfo = {};
5525        populateResponseInfo(responseInfo, serial, responseType, e);
5526        Return<void> retStatus
5527                = radioService[slotId]->mRadioResponse->acknowledgeIncomingGsmSmsWithPduResponse(
5528                responseInfo);
5529        radioService[slotId]->checkReturnStatus(retStatus);
5530    } else {
5531        RLOGE("acknowledgeIncomingGsmSmsWithPduResponse: radioService[%d]->mRadioResponse "
5532                "== NULL", slotId);
5533    }
5534
5535    return 0;
5536}
5537
5538int radio::sendEnvelopeWithStatusResponse(int slotId,
5539                                         int responseType, int serial, RIL_Errno e, void *response,
5540                                         size_t responseLen) {
5541#if VDBG
5542    RLOGD("sendEnvelopeWithStatusResponse: serial %d", serial);
5543#endif
5544
5545    if (radioService[slotId]->mRadioResponse != NULL) {
5546        RadioResponseInfo responseInfo = {};
5547        IccIoResult result = responseIccIo(responseInfo, serial, responseType, e,
5548                response, responseLen);
5549
5550        Return<void> retStatus
5551                = radioService[slotId]->mRadioResponse->sendEnvelopeWithStatusResponse(responseInfo,
5552                result);
5553        radioService[slotId]->checkReturnStatus(retStatus);
5554    } else {
5555        RLOGE("sendEnvelopeWithStatusResponse: radioService[%d]->mRadioResponse == NULL",
5556                slotId);
5557    }
5558
5559    return 0;
5560}
5561
5562int radio::getVoiceRadioTechnologyResponse(int slotId,
5563                                          int responseType, int serial, RIL_Errno e,
5564                                          void *response, size_t responseLen) {
5565#if VDBG
5566    RLOGD("getVoiceRadioTechnologyResponse: serial %d", serial);
5567#endif
5568
5569    if (radioService[slotId]->mRadioResponse != NULL) {
5570        RadioResponseInfo responseInfo = {};
5571        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
5572        Return<void> retStatus
5573                = radioService[slotId]->mRadioResponse->getVoiceRadioTechnologyResponse(
5574                responseInfo, (RadioTechnology) ret);
5575        radioService[slotId]->checkReturnStatus(retStatus);
5576    } else {
5577        RLOGE("getVoiceRadioTechnologyResponse: radioService[%d]->mRadioResponse == NULL",
5578                slotId);
5579    }
5580
5581    return 0;
5582}
5583
5584int radio::getCellInfoListResponse(int slotId,
5585                                   int responseType,
5586                                   int serial, RIL_Errno e, void *response,
5587                                   size_t responseLen) {
5588#if VDBG
5589    RLOGD("getCellInfoListResponse: serial %d", serial);
5590#endif
5591
5592    if (radioService[slotId]->mRadioResponse != NULL) {
5593        RadioResponseInfo responseInfo = {};
5594        populateResponseInfo(responseInfo, serial, responseType, e);
5595
5596        hidl_vec<CellInfo> ret;
5597        if ((response == NULL && responseLen != 0)
5598                || responseLen % sizeof(RIL_CellInfo_v12) != 0) {
5599            RLOGE("getCellInfoListResponse: Invalid response");
5600            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
5601        } else {
5602            convertRilCellInfoListToHal(response, responseLen, ret);
5603        }
5604
5605        Return<void> retStatus = radioService[slotId]->mRadioResponse->getCellInfoListResponse(
5606                responseInfo, ret);
5607        radioService[slotId]->checkReturnStatus(retStatus);
5608    } else {
5609        RLOGE("getCellInfoListResponse: radioService[%d]->mRadioResponse == NULL", slotId);
5610    }
5611
5612    return 0;
5613}
5614
5615int radio::setCellInfoListRateResponse(int slotId,
5616                                       int responseType,
5617                                       int serial, RIL_Errno e, void *response,
5618                                       size_t responseLen) {
5619#if VDBG
5620    RLOGD("setCellInfoListRateResponse: serial %d", serial);
5621#endif
5622
5623    if (radioService[slotId]->mRadioResponse != NULL) {
5624        RadioResponseInfo responseInfo = {};
5625        populateResponseInfo(responseInfo, serial, responseType, e);
5626        Return<void> retStatus
5627                = radioService[slotId]->mRadioResponse->setCellInfoListRateResponse(responseInfo);
5628        radioService[slotId]->checkReturnStatus(retStatus);
5629    } else {
5630        RLOGE("setCellInfoListRateResponse: radioService[%d]->mRadioResponse == NULL",
5631                slotId);
5632    }
5633
5634    return 0;
5635}
5636
5637int radio::setInitialAttachApnResponse(int slotId,
5638                                       int responseType, int serial, RIL_Errno e,
5639                                       void *response, size_t responseLen) {
5640#if VDBG
5641    RLOGD("setInitialAttachApnResponse: serial %d", serial);
5642#endif
5643
5644    if (radioService[slotId]->mRadioResponse != NULL) {
5645        RadioResponseInfo responseInfo = {};
5646        populateResponseInfo(responseInfo, serial, responseType, e);
5647        Return<void> retStatus
5648                = radioService[slotId]->mRadioResponse->setInitialAttachApnResponse(responseInfo);
5649        radioService[slotId]->checkReturnStatus(retStatus);
5650    } else {
5651        RLOGE("setInitialAttachApnResponse: radioService[%d]->mRadioResponse == NULL",
5652                slotId);
5653    }
5654
5655    return 0;
5656}
5657
5658int radio::getImsRegistrationStateResponse(int slotId,
5659                                           int responseType, int serial, RIL_Errno e,
5660                                           void *response, size_t responseLen) {
5661#if VDBG
5662    RLOGD("getImsRegistrationStateResponse: serial %d", serial);
5663#endif
5664
5665    if (radioService[slotId]->mRadioResponse != NULL) {
5666        RadioResponseInfo responseInfo = {};
5667        populateResponseInfo(responseInfo, serial, responseType, e);
5668        bool isRegistered = false;
5669        int ratFamily = 0;
5670        int numInts = responseLen / sizeof(int);
5671        if (response == NULL || numInts != 2) {
5672            RLOGE("getImsRegistrationStateResponse Invalid response: NULL");
5673            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
5674        } else {
5675            int *pInt = (int *) response;
5676            isRegistered = pInt[0] == 1 ? true : false;
5677            ratFamily = pInt[1];
5678        }
5679        Return<void> retStatus
5680                = radioService[slotId]->mRadioResponse->getImsRegistrationStateResponse(
5681                responseInfo, isRegistered, (RadioTechnologyFamily) ratFamily);
5682        radioService[slotId]->checkReturnStatus(retStatus);
5683    } else {
5684        RLOGE("getImsRegistrationStateResponse: radioService[%d]->mRadioResponse == NULL",
5685                slotId);
5686    }
5687
5688    return 0;
5689}
5690
5691int radio::sendImsSmsResponse(int slotId,
5692                              int responseType, int serial, RIL_Errno e, void *response,
5693                              size_t responseLen) {
5694#if VDBG
5695    RLOGD("sendImsSmsResponse: serial %d", serial);
5696#endif
5697
5698    if (radioService[slotId]->mRadioResponse != NULL) {
5699        RadioResponseInfo responseInfo = {};
5700        SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response,
5701                responseLen);
5702
5703        Return<void> retStatus
5704                = radioService[slotId]->mRadioResponse->sendImsSmsResponse(responseInfo, result);
5705        radioService[slotId]->checkReturnStatus(retStatus);
5706    } else {
5707        RLOGE("sendSmsResponse: radioService[%d]->mRadioResponse == NULL", slotId);
5708    }
5709
5710    return 0;
5711}
5712
5713int radio::iccTransmitApduBasicChannelResponse(int slotId,
5714                                               int responseType, int serial, RIL_Errno e,
5715                                               void *response, size_t responseLen) {
5716#if VDBG
5717    RLOGD("iccTransmitApduBasicChannelResponse: serial %d", serial);
5718#endif
5719
5720    if (radioService[slotId]->mRadioResponse != NULL) {
5721        RadioResponseInfo responseInfo = {};
5722        IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response,
5723                responseLen);
5724
5725        Return<void> retStatus
5726                = radioService[slotId]->mRadioResponse->iccTransmitApduBasicChannelResponse(
5727                responseInfo, result);
5728        radioService[slotId]->checkReturnStatus(retStatus);
5729    } else {
5730        RLOGE("iccTransmitApduBasicChannelResponse: radioService[%d]->mRadioResponse "
5731                "== NULL", slotId);
5732    }
5733
5734    return 0;
5735}
5736
5737int radio::iccOpenLogicalChannelResponse(int slotId,
5738                                         int responseType, int serial, RIL_Errno e, void *response,
5739                                         size_t responseLen) {
5740#if VDBG
5741    RLOGD("iccOpenLogicalChannelResponse: serial %d", serial);
5742#endif
5743
5744    if (radioService[slotId]->mRadioResponse != NULL) {
5745        RadioResponseInfo responseInfo = {};
5746        populateResponseInfo(responseInfo, serial, responseType, e);
5747        int channelId = -1;
5748        hidl_vec<int8_t> selectResponse;
5749        int numInts = responseLen / sizeof(int);
5750        if (response == NULL || responseLen % sizeof(int) != 0) {
5751            RLOGE("iccOpenLogicalChannelResponse Invalid response: NULL");
5752            if (response != NULL) {
5753                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
5754            }
5755        } else {
5756            int *pInt = (int *) response;
5757            channelId = pInt[0];
5758            selectResponse.resize(numInts - 1);
5759            for (int i = 1; i < numInts; i++) {
5760                selectResponse[i - 1] = (int8_t) pInt[i];
5761            }
5762        }
5763        Return<void> retStatus
5764                = radioService[slotId]->mRadioResponse->iccOpenLogicalChannelResponse(responseInfo,
5765                channelId, selectResponse);
5766        radioService[slotId]->checkReturnStatus(retStatus);
5767    } else {
5768        RLOGE("iccOpenLogicalChannelResponse: radioService[%d]->mRadioResponse == NULL",
5769                slotId);
5770    }
5771
5772    return 0;
5773}
5774
5775int radio::iccCloseLogicalChannelResponse(int slotId,
5776                                          int responseType, int serial, RIL_Errno e,
5777                                          void *response, size_t responseLen) {
5778#if VDBG
5779    RLOGD("iccCloseLogicalChannelResponse: serial %d", serial);
5780#endif
5781
5782    if (radioService[slotId]->mRadioResponse != NULL) {
5783        RadioResponseInfo responseInfo = {};
5784        populateResponseInfo(responseInfo, serial, responseType, e);
5785        Return<void> retStatus
5786                = radioService[slotId]->mRadioResponse->iccCloseLogicalChannelResponse(
5787                responseInfo);
5788        radioService[slotId]->checkReturnStatus(retStatus);
5789    } else {
5790        RLOGE("iccCloseLogicalChannelResponse: radioService[%d]->mRadioResponse == NULL",
5791                slotId);
5792    }
5793
5794    return 0;
5795}
5796
5797int radio::iccTransmitApduLogicalChannelResponse(int slotId,
5798                                                 int responseType, int serial, RIL_Errno e,
5799                                                 void *response, size_t responseLen) {
5800#if VDBG
5801    RLOGD("iccTransmitApduLogicalChannelResponse: serial %d", serial);
5802#endif
5803
5804    if (radioService[slotId]->mRadioResponse != NULL) {
5805        RadioResponseInfo responseInfo = {};
5806        IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response,
5807                responseLen);
5808
5809        Return<void> retStatus
5810                = radioService[slotId]->mRadioResponse->iccTransmitApduLogicalChannelResponse(
5811                responseInfo, result);
5812        radioService[slotId]->checkReturnStatus(retStatus);
5813    } else {
5814        RLOGE("iccTransmitApduLogicalChannelResponse: radioService[%d]->mRadioResponse "
5815                "== NULL", slotId);
5816    }
5817
5818    return 0;
5819}
5820
5821int radio::nvReadItemResponse(int slotId,
5822                              int responseType, int serial, RIL_Errno e,
5823                              void *response, size_t responseLen) {
5824#if VDBG
5825    RLOGD("nvReadItemResponse: serial %d", serial);
5826#endif
5827
5828    if (radioService[slotId]->mRadioResponse != NULL) {
5829        RadioResponseInfo responseInfo = {};
5830        populateResponseInfo(responseInfo, serial, responseType, e);
5831        Return<void> retStatus = radioService[slotId]->mRadioResponse->nvReadItemResponse(
5832                responseInfo,
5833                convertCharPtrToHidlString((char *) response));
5834        radioService[slotId]->checkReturnStatus(retStatus);
5835    } else {
5836        RLOGE("nvReadItemResponse: radioService[%d]->mRadioResponse == NULL", slotId);
5837    }
5838
5839    return 0;
5840}
5841
5842int radio::nvWriteItemResponse(int slotId,
5843                               int responseType, int serial, RIL_Errno e,
5844                               void *response, size_t responseLen) {
5845#if VDBG
5846    RLOGD("nvWriteItemResponse: serial %d", serial);
5847#endif
5848
5849    if (radioService[slotId]->mRadioResponse != NULL) {
5850        RadioResponseInfo responseInfo = {};
5851        populateResponseInfo(responseInfo, serial, responseType, e);
5852        Return<void> retStatus
5853                = radioService[slotId]->mRadioResponse->nvWriteItemResponse(responseInfo);
5854        radioService[slotId]->checkReturnStatus(retStatus);
5855    } else {
5856        RLOGE("nvWriteItemResponse: radioService[%d]->mRadioResponse == NULL", slotId);
5857    }
5858
5859    return 0;
5860}
5861
5862int radio::nvWriteCdmaPrlResponse(int slotId,
5863                                  int responseType, int serial, RIL_Errno e,
5864                                  void *response, size_t responseLen) {
5865#if VDBG
5866    RLOGD("nvWriteCdmaPrlResponse: serial %d", serial);
5867#endif
5868
5869    if (radioService[slotId]->mRadioResponse != NULL) {
5870        RadioResponseInfo responseInfo = {};
5871        populateResponseInfo(responseInfo, serial, responseType, e);
5872        Return<void> retStatus
5873                = radioService[slotId]->mRadioResponse->nvWriteCdmaPrlResponse(responseInfo);
5874        radioService[slotId]->checkReturnStatus(retStatus);
5875    } else {
5876        RLOGE("nvWriteCdmaPrlResponse: radioService[%d]->mRadioResponse == NULL", slotId);
5877    }
5878
5879    return 0;
5880}
5881
5882int radio::nvResetConfigResponse(int slotId,
5883                                 int responseType, int serial, RIL_Errno e,
5884                                 void *response, size_t responseLen) {
5885#if VDBG
5886    RLOGD("nvResetConfigResponse: serial %d", serial);
5887#endif
5888
5889    if (radioService[slotId]->mRadioResponse != NULL) {
5890        RadioResponseInfo responseInfo = {};
5891        populateResponseInfo(responseInfo, serial, responseType, e);
5892        Return<void> retStatus
5893                = radioService[slotId]->mRadioResponse->nvResetConfigResponse(responseInfo);
5894        radioService[slotId]->checkReturnStatus(retStatus);
5895    } else {
5896        RLOGE("nvResetConfigResponse: radioService[%d]->mRadioResponse == NULL", slotId);
5897    }
5898
5899    return 0;
5900}
5901
5902int radio::setUiccSubscriptionResponse(int slotId,
5903                                       int responseType, int serial, RIL_Errno e,
5904                                       void *response, size_t responseLen) {
5905#if VDBG
5906    RLOGD("setUiccSubscriptionResponse: serial %d", serial);
5907#endif
5908
5909    if (radioService[slotId]->mRadioResponse != NULL) {
5910        RadioResponseInfo responseInfo = {};
5911        populateResponseInfo(responseInfo, serial, responseType, e);
5912        Return<void> retStatus
5913                = radioService[slotId]->mRadioResponse->setUiccSubscriptionResponse(responseInfo);
5914        radioService[slotId]->checkReturnStatus(retStatus);
5915    } else {
5916        RLOGE("setUiccSubscriptionResponse: radioService[%d]->mRadioResponse == NULL",
5917                slotId);
5918    }
5919
5920    return 0;
5921}
5922
5923int radio::setDataAllowedResponse(int slotId,
5924                                  int responseType, int serial, RIL_Errno e,
5925                                  void *response, size_t responseLen) {
5926#if VDBG
5927    RLOGD("setDataAllowedResponse: serial %d", serial);
5928#endif
5929
5930    if (radioService[slotId]->mRadioResponse != NULL) {
5931        RadioResponseInfo responseInfo = {};
5932        populateResponseInfo(responseInfo, serial, responseType, e);
5933        Return<void> retStatus
5934                = radioService[slotId]->mRadioResponse->setDataAllowedResponse(responseInfo);
5935        radioService[slotId]->checkReturnStatus(retStatus);
5936    } else {
5937        RLOGE("setDataAllowedResponse: radioService[%d]->mRadioResponse == NULL", slotId);
5938    }
5939
5940    return 0;
5941}
5942
5943int radio::getHardwareConfigResponse(int slotId,
5944                                     int responseType, int serial, RIL_Errno e,
5945                                     void *response, size_t responseLen) {
5946#if VDBG
5947    RLOGD("getHardwareConfigResponse: serial %d", serial);
5948#endif
5949
5950    if (radioService[slotId]->mRadioResponse != NULL) {
5951        RadioResponseInfo responseInfo = {};
5952        populateResponseInfo(responseInfo, serial, responseType, e);
5953
5954        hidl_vec<HardwareConfig> result;
5955        if ((response == NULL && responseLen != 0)
5956                || responseLen % sizeof(RIL_HardwareConfig) != 0) {
5957            RLOGE("hardwareConfigChangedInd: invalid response");
5958            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
5959        } else {
5960            convertRilHardwareConfigListToHal(response, responseLen, result);
5961        }
5962
5963        Return<void> retStatus = radioService[slotId]->mRadioResponse->getHardwareConfigResponse(
5964                responseInfo, result);
5965        radioService[slotId]->checkReturnStatus(retStatus);
5966    } else {
5967        RLOGE("getHardwareConfigResponse: radioService[%d]->mRadioResponse == NULL", slotId);
5968    }
5969
5970    return 0;
5971}
5972
5973int radio::requestIccSimAuthenticationResponse(int slotId,
5974                                               int responseType, int serial, RIL_Errno e,
5975                                               void *response, size_t responseLen) {
5976#if VDBG
5977    RLOGD("requestIccSimAuthenticationResponse: serial %d", serial);
5978#endif
5979
5980    if (radioService[slotId]->mRadioResponse != NULL) {
5981        RadioResponseInfo responseInfo = {};
5982        IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response,
5983                responseLen);
5984
5985        Return<void> retStatus
5986                = radioService[slotId]->mRadioResponse->requestIccSimAuthenticationResponse(
5987                responseInfo, result);
5988        radioService[slotId]->checkReturnStatus(retStatus);
5989    } else {
5990        RLOGE("requestIccSimAuthenticationResponse: radioService[%d]->mRadioResponse "
5991                "== NULL", slotId);
5992    }
5993
5994    return 0;
5995}
5996
5997int radio::setDataProfileResponse(int slotId,
5998                                  int responseType, int serial, RIL_Errno e,
5999                                  void *response, size_t responseLen) {
6000#if VDBG
6001    RLOGD("setDataProfileResponse: serial %d", serial);
6002#endif
6003
6004    if (radioService[slotId]->mRadioResponse != NULL) {
6005        RadioResponseInfo responseInfo = {};
6006        populateResponseInfo(responseInfo, serial, responseType, e);
6007        Return<void> retStatus
6008                = radioService[slotId]->mRadioResponse->setDataProfileResponse(responseInfo);
6009        radioService[slotId]->checkReturnStatus(retStatus);
6010    } else {
6011        RLOGE("setDataProfileResponse: radioService[%d]->mRadioResponse == NULL", slotId);
6012    }
6013
6014    return 0;
6015}
6016
6017int radio::requestShutdownResponse(int slotId,
6018                                  int responseType, int serial, RIL_Errno e,
6019                                  void *response, size_t responseLen) {
6020#if VDBG
6021    RLOGD("requestShutdownResponse: serial %d", serial);
6022#endif
6023
6024    if (radioService[slotId]->mRadioResponse != NULL) {
6025        RadioResponseInfo responseInfo = {};
6026        populateResponseInfo(responseInfo, serial, responseType, e);
6027        Return<void> retStatus
6028                = radioService[slotId]->mRadioResponse->requestShutdownResponse(responseInfo);
6029        radioService[slotId]->checkReturnStatus(retStatus);
6030    } else {
6031        RLOGE("requestShutdownResponse: radioService[%d]->mRadioResponse == NULL", slotId);
6032    }
6033
6034    return 0;
6035}
6036
6037void responseRadioCapability(RadioResponseInfo& responseInfo, int serial,
6038        int responseType, RIL_Errno e, void *response, size_t responseLen, RadioCapability& rc) {
6039    populateResponseInfo(responseInfo, serial, responseType, e);
6040
6041    if (response == NULL || responseLen != sizeof(RIL_RadioCapability)) {
6042        RLOGE("responseRadioCapability: Invalid response");
6043        if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
6044        rc.logicalModemUuid = hidl_string();
6045    } else {
6046        convertRilRadioCapabilityToHal(response, responseLen, rc);
6047    }
6048}
6049
6050int radio::getRadioCapabilityResponse(int slotId,
6051                                     int responseType, int serial, RIL_Errno e,
6052                                     void *response, size_t responseLen) {
6053#if VDBG
6054    RLOGD("getRadioCapabilityResponse: serial %d", serial);
6055#endif
6056
6057    if (radioService[slotId]->mRadioResponse != NULL) {
6058        RadioResponseInfo responseInfo = {};
6059        RadioCapability result = {};
6060        responseRadioCapability(responseInfo, serial, responseType, e, response, responseLen,
6061                result);
6062        Return<void> retStatus = radioService[slotId]->mRadioResponse->getRadioCapabilityResponse(
6063                responseInfo, result);
6064        radioService[slotId]->checkReturnStatus(retStatus);
6065    } else {
6066        RLOGE("getRadioCapabilityResponse: radioService[%d]->mRadioResponse == NULL", slotId);
6067    }
6068
6069    return 0;
6070}
6071
6072int radio::setRadioCapabilityResponse(int slotId,
6073                                     int responseType, int serial, RIL_Errno e,
6074                                     void *response, size_t responseLen) {
6075#if VDBG
6076    RLOGD("setRadioCapabilityResponse: serial %d", serial);
6077#endif
6078
6079    if (radioService[slotId]->mRadioResponse != NULL) {
6080        RadioResponseInfo responseInfo = {};
6081        RadioCapability result = {};
6082        responseRadioCapability(responseInfo, serial, responseType, e, response, responseLen,
6083                result);
6084        Return<void> retStatus = radioService[slotId]->mRadioResponse->setRadioCapabilityResponse(
6085                responseInfo, result);
6086        radioService[slotId]->checkReturnStatus(retStatus);
6087    } else {
6088        RLOGE("setRadioCapabilityResponse: radioService[%d]->mRadioResponse == NULL", slotId);
6089    }
6090
6091    return 0;
6092}
6093
6094LceStatusInfo responseLceStatusInfo(RadioResponseInfo& responseInfo, int serial, int responseType,
6095                                    RIL_Errno e, void *response, size_t responseLen) {
6096    populateResponseInfo(responseInfo, serial, responseType, e);
6097    LceStatusInfo result = {};
6098
6099    if (response == NULL || responseLen != sizeof(RIL_LceStatusInfo)) {
6100        RLOGE("Invalid response: NULL");
6101        if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
6102    } else {
6103        RIL_LceStatusInfo *resp = (RIL_LceStatusInfo *) response;
6104        result.lceStatus = (LceStatus) resp->lce_status;
6105        result.actualIntervalMs = (uint8_t) resp->actual_interval_ms;
6106    }
6107    return result;
6108}
6109
6110int radio::startLceServiceResponse(int slotId,
6111                                   int responseType, int serial, RIL_Errno e,
6112                                   void *response, size_t responseLen) {
6113#if VDBG
6114    RLOGD("startLceServiceResponse: serial %d", serial);
6115#endif
6116
6117    if (radioService[slotId]->mRadioResponse != NULL) {
6118        RadioResponseInfo responseInfo = {};
6119        LceStatusInfo result = responseLceStatusInfo(responseInfo, serial, responseType, e,
6120                response, responseLen);
6121
6122        Return<void> retStatus
6123                = radioService[slotId]->mRadioResponse->startLceServiceResponse(responseInfo,
6124                result);
6125        radioService[slotId]->checkReturnStatus(retStatus);
6126    } else {
6127        RLOGE("startLceServiceResponse: radioService[%d]->mRadioResponse == NULL", slotId);
6128    }
6129
6130    return 0;
6131}
6132
6133int radio::stopLceServiceResponse(int slotId,
6134                                  int responseType, int serial, RIL_Errno e,
6135                                  void *response, size_t responseLen) {
6136#if VDBG
6137    RLOGD("stopLceServiceResponse: serial %d", serial);
6138#endif
6139
6140    if (radioService[slotId]->mRadioResponse != NULL) {
6141        RadioResponseInfo responseInfo = {};
6142        LceStatusInfo result = responseLceStatusInfo(responseInfo, serial, responseType, e,
6143                response, responseLen);
6144
6145        Return<void> retStatus
6146                = radioService[slotId]->mRadioResponse->stopLceServiceResponse(responseInfo,
6147                result);
6148        radioService[slotId]->checkReturnStatus(retStatus);
6149    } else {
6150        RLOGE("stopLceServiceResponse: radioService[%d]->mRadioResponse == NULL", slotId);
6151    }
6152
6153    return 0;
6154}
6155
6156int radio::pullLceDataResponse(int slotId,
6157                               int responseType, int serial, RIL_Errno e,
6158                               void *response, size_t responseLen) {
6159#if VDBG
6160    RLOGD("pullLceDataResponse: serial %d", serial);
6161#endif
6162
6163    if (radioService[slotId]->mRadioResponse != NULL) {
6164        RadioResponseInfo responseInfo = {};
6165        populateResponseInfo(responseInfo, serial, responseType, e);
6166
6167        LceDataInfo result = {};
6168        if (response == NULL || responseLen != sizeof(RIL_LceDataInfo)) {
6169            RLOGE("pullLceDataResponse: Invalid response");
6170            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
6171        } else {
6172            convertRilLceDataInfoToHal(response, responseLen, result);
6173        }
6174
6175        Return<void> retStatus = radioService[slotId]->mRadioResponse->pullLceDataResponse(
6176                responseInfo, result);
6177        radioService[slotId]->checkReturnStatus(retStatus);
6178    } else {
6179        RLOGE("pullLceDataResponse: radioService[%d]->mRadioResponse == NULL", slotId);
6180    }
6181
6182    return 0;
6183}
6184
6185int radio::getModemActivityInfoResponse(int slotId,
6186                                        int responseType, int serial, RIL_Errno e,
6187                                        void *response, size_t responseLen) {
6188#if VDBG
6189    RLOGD("getModemActivityInfoResponse: serial %d", serial);
6190#endif
6191
6192    if (radioService[slotId]->mRadioResponse != NULL) {
6193        RadioResponseInfo responseInfo = {};
6194        populateResponseInfo(responseInfo, serial, responseType, e);
6195        ActivityStatsInfo info;
6196        if (response == NULL || responseLen != sizeof(RIL_ActivityStatsInfo)) {
6197            RLOGE("getModemActivityInfoResponse Invalid response: NULL");
6198            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
6199        } else {
6200            RIL_ActivityStatsInfo *resp = (RIL_ActivityStatsInfo *)response;
6201            info.sleepModeTimeMs = resp->sleep_mode_time_ms;
6202            info.idleModeTimeMs = resp->idle_mode_time_ms;
6203            for(int i = 0; i < RIL_NUM_TX_POWER_LEVELS; i++) {
6204                info.txmModetimeMs[i] = resp->tx_mode_time_ms[i];
6205            }
6206            info.rxModeTimeMs = resp->rx_mode_time_ms;
6207        }
6208
6209        Return<void> retStatus
6210                = radioService[slotId]->mRadioResponse->getModemActivityInfoResponse(responseInfo,
6211                info);
6212        radioService[slotId]->checkReturnStatus(retStatus);
6213    } else {
6214        RLOGE("getModemActivityInfoResponse: radioService[%d]->mRadioResponse == NULL",
6215                slotId);
6216    }
6217
6218    return 0;
6219}
6220
6221int radio::setAllowedCarriersResponse(int slotId,
6222                                      int responseType, int serial, RIL_Errno e,
6223                                      void *response, size_t responseLen) {
6224#if VDBG
6225    RLOGD("setAllowedCarriersResponse: serial %d", serial);
6226#endif
6227
6228    if (radioService[slotId]->mRadioResponse != NULL) {
6229        RadioResponseInfo responseInfo = {};
6230        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
6231        Return<void> retStatus
6232                = radioService[slotId]->mRadioResponse->setAllowedCarriersResponse(responseInfo,
6233                ret);
6234        radioService[slotId]->checkReturnStatus(retStatus);
6235    } else {
6236        RLOGE("setAllowedCarriersResponse: radioService[%d]->mRadioResponse == NULL",
6237                slotId);
6238    }
6239
6240    return 0;
6241}
6242
6243int radio::getAllowedCarriersResponse(int slotId,
6244                                      int responseType, int serial, RIL_Errno e,
6245                                      void *response, size_t responseLen) {
6246#if VDBG
6247    RLOGD("getAllowedCarriersResponse: serial %d", serial);
6248#endif
6249
6250    if (radioService[slotId]->mRadioResponse != NULL) {
6251        RadioResponseInfo responseInfo = {};
6252        populateResponseInfo(responseInfo, serial, responseType, e);
6253        CarrierRestrictions carrierInfo = {};
6254        bool allAllowed = true;
6255        if (response == NULL) {
6256#if VDBG
6257            RLOGD("getAllowedCarriersResponse response is NULL: all allowed");
6258#endif
6259            carrierInfo.allowedCarriers.resize(0);
6260            carrierInfo.excludedCarriers.resize(0);
6261        } else if (responseLen != sizeof(RIL_CarrierRestrictions)) {
6262            RLOGE("getAllowedCarriersResponse Invalid response");
6263            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
6264        } else {
6265            RIL_CarrierRestrictions *pCr = (RIL_CarrierRestrictions *)response;
6266            if (pCr->len_allowed_carriers > 0 || pCr->len_excluded_carriers > 0) {
6267                allAllowed = false;
6268            }
6269
6270            carrierInfo.allowedCarriers.resize(pCr->len_allowed_carriers);
6271            for(int i = 0; i < pCr->len_allowed_carriers; i++) {
6272                RIL_Carrier *carrier = pCr->allowed_carriers + i;
6273                carrierInfo.allowedCarriers[i].mcc = convertCharPtrToHidlString(carrier->mcc);
6274                carrierInfo.allowedCarriers[i].mnc = convertCharPtrToHidlString(carrier->mnc);
6275                carrierInfo.allowedCarriers[i].matchType = (CarrierMatchType) carrier->match_type;
6276                carrierInfo.allowedCarriers[i].matchData =
6277                        convertCharPtrToHidlString(carrier->match_data);
6278            }
6279
6280            carrierInfo.excludedCarriers.resize(pCr->len_excluded_carriers);
6281            for(int i = 0; i < pCr->len_excluded_carriers; i++) {
6282                RIL_Carrier *carrier = pCr->excluded_carriers + i;
6283                carrierInfo.excludedCarriers[i].mcc = convertCharPtrToHidlString(carrier->mcc);
6284                carrierInfo.excludedCarriers[i].mnc = convertCharPtrToHidlString(carrier->mnc);
6285                carrierInfo.excludedCarriers[i].matchType = (CarrierMatchType) carrier->match_type;
6286                carrierInfo.excludedCarriers[i].matchData =
6287                        convertCharPtrToHidlString(carrier->match_data);
6288            }
6289        }
6290
6291        Return<void> retStatus
6292                = radioService[slotId]->mRadioResponse->getAllowedCarriersResponse(responseInfo,
6293                allAllowed, carrierInfo);
6294        radioService[slotId]->checkReturnStatus(retStatus);
6295    } else {
6296        RLOGE("getAllowedCarriersResponse: radioService[%d]->mRadioResponse == NULL",
6297                slotId);
6298    }
6299
6300    return 0;
6301}
6302
6303int radio::sendDeviceStateResponse(int slotId,
6304                              int responseType, int serial, RIL_Errno e,
6305                              void *response, size_t responselen) {
6306#if VDBG
6307    RLOGD("sendDeviceStateResponse: serial %d", serial);
6308#endif
6309
6310    if (radioService[slotId]->mRadioResponse != NULL) {
6311        RadioResponseInfo responseInfo = {};
6312        populateResponseInfo(responseInfo, serial, responseType, e);
6313        Return<void> retStatus
6314                = radioService[slotId]->mRadioResponse->sendDeviceStateResponse(responseInfo);
6315        radioService[slotId]->checkReturnStatus(retStatus);
6316    } else {
6317        RLOGE("sendDeviceStateResponse: radioService[%d]->mRadioResponse == NULL", slotId);
6318    }
6319
6320    return 0;
6321}
6322
6323int radio::setIndicationFilterResponse(int slotId,
6324                              int responseType, int serial, RIL_Errno e,
6325                              void *response, size_t responselen) {
6326#if VDBG
6327    RLOGD("setIndicationFilterResponse: serial %d", serial);
6328#endif
6329
6330    if (radioService[slotId]->mRadioResponse != NULL) {
6331        RadioResponseInfo responseInfo = {};
6332        populateResponseInfo(responseInfo, serial, responseType, e);
6333        Return<void> retStatus
6334                = radioService[slotId]->mRadioResponse->setIndicationFilterResponse(responseInfo);
6335        radioService[slotId]->checkReturnStatus(retStatus);
6336    } else {
6337        RLOGE("setIndicationFilterResponse: radioService[%d]->mRadioResponse == NULL",
6338                slotId);
6339    }
6340
6341    return 0;
6342}
6343
6344
6345int radio::setSimCardPowerResponse(int slotId,
6346                                   int responseType, int serial, RIL_Errno e,
6347                                   void *response, size_t responseLen) {
6348#if VDBG
6349    RLOGD("setSimCardPowerResponse: serial %d", serial);
6350#endif
6351
6352    if (radioService[slotId]->mRadioResponse != NULL) {
6353        RadioResponseInfo responseInfo = {};
6354        populateResponseInfo(responseInfo, serial, responseType, e);
6355        Return<void> retStatus
6356                = radioService[slotId]->mRadioResponse->setSimCardPowerResponse(responseInfo);
6357        radioService[slotId]->checkReturnStatus(retStatus);
6358    } else {
6359        RLOGE("setSimCardPowerResponse: radioService[%d]->mRadioResponse == NULL", slotId);
6360    }
6361
6362    return 0;
6363}
6364
6365int radio::sendRequestRawResponse(int slotId,
6366                                  int responseType, int serial, RIL_Errno e,
6367                                  void *response, size_t responseLen) {
6368#if VDBG
6369   RLOGD("sendRequestRawResponse: serial %d", serial);
6370#endif
6371
6372    if (oemHookService[slotId]->mOemHookResponse != NULL) {
6373        RadioResponseInfo responseInfo = {};
6374        populateResponseInfo(responseInfo, serial, responseType, e);
6375        hidl_vec<uint8_t> data;
6376
6377        if (response == NULL) {
6378            RLOGE("sendRequestRawResponse: Invalid response");
6379            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
6380        } else {
6381            data.setToExternal((uint8_t *) response, responseLen);
6382        }
6383        Return<void> retStatus = oemHookService[slotId]->mOemHookResponse->
6384                sendRequestRawResponse(responseInfo, data);
6385        checkReturnStatus(slotId, retStatus, false);
6386    } else {
6387        RLOGE("sendRequestRawResponse: oemHookService[%d]->mOemHookResponse == NULL",
6388                slotId);
6389    }
6390
6391    return 0;
6392}
6393
6394int radio::sendRequestStringsResponse(int slotId,
6395                                      int responseType, int serial, RIL_Errno e,
6396                                      void *response, size_t responseLen) {
6397#if VDBG
6398    RLOGD("sendRequestStringsResponse: serial %d", serial);
6399#endif
6400
6401    if (oemHookService[slotId]->mOemHookResponse != NULL) {
6402        RadioResponseInfo responseInfo = {};
6403        populateResponseInfo(responseInfo, serial, responseType, e);
6404        hidl_vec<hidl_string> data;
6405
6406        if ((response == NULL && responseLen != 0) || responseLen % sizeof(char *) != 0) {
6407            RLOGE("sendRequestStringsResponse Invalid response: NULL");
6408            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
6409        } else {
6410            char **resp = (char **) response;
6411            int numStrings = responseLen / sizeof(char *);
6412            data.resize(numStrings);
6413            for (int i = 0; i < numStrings; i++) {
6414                data[i] = convertCharPtrToHidlString(resp[i]);
6415            }
6416        }
6417        Return<void> retStatus
6418                = oemHookService[slotId]->mOemHookResponse->sendRequestStringsResponse(
6419                responseInfo, data);
6420        checkReturnStatus(slotId, retStatus, false);
6421    } else {
6422        RLOGE("sendRequestStringsResponse: oemHookService[%d]->mOemHookResponse == "
6423                "NULL", slotId);
6424    }
6425
6426    return 0;
6427}
6428
6429// Radio Indication functions
6430
6431RadioIndicationType convertIntToRadioIndicationType(int indicationType) {
6432    return indicationType == RESPONSE_UNSOLICITED ? (RadioIndicationType::UNSOLICITED) :
6433            (RadioIndicationType::UNSOLICITED_ACK_EXP);
6434}
6435
6436int radio::radioStateChangedInd(int slotId,
6437                                 int indicationType, int token, RIL_Errno e, void *response,
6438                                 size_t responseLen) {
6439    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6440        RadioState radioState =
6441                (RadioState) CALL_ONSTATEREQUEST(slotId);
6442        RLOGD("radioStateChangedInd: radioState %d", radioState);
6443        Return<void> retStatus = radioService[slotId]->mRadioIndication->radioStateChanged(
6444                convertIntToRadioIndicationType(indicationType), radioState);
6445        radioService[slotId]->checkReturnStatus(retStatus);
6446    } else {
6447        RLOGE("radioStateChangedInd: radioService[%d]->mRadioIndication == NULL", slotId);
6448    }
6449
6450    return 0;
6451}
6452
6453int radio::callStateChangedInd(int slotId,
6454                               int indicationType, int token, RIL_Errno e, void *response,
6455                               size_t responseLen) {
6456    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6457#if VDBG
6458        RLOGD("callStateChangedInd");
6459#endif
6460        Return<void> retStatus = radioService[slotId]->mRadioIndication->callStateChanged(
6461                convertIntToRadioIndicationType(indicationType));
6462        radioService[slotId]->checkReturnStatus(retStatus);
6463    } else {
6464        RLOGE("callStateChangedInd: radioService[%d]->mRadioIndication == NULL", slotId);
6465    }
6466
6467    return 0;
6468}
6469
6470int radio::networkStateChangedInd(int slotId,
6471                                  int indicationType, int token, RIL_Errno e, void *response,
6472                                  size_t responseLen) {
6473    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6474#if VDBG
6475        RLOGD("networkStateChangedInd");
6476#endif
6477        Return<void> retStatus = radioService[slotId]->mRadioIndication->networkStateChanged(
6478                convertIntToRadioIndicationType(indicationType));
6479        radioService[slotId]->checkReturnStatus(retStatus);
6480    } else {
6481        RLOGE("networkStateChangedInd: radioService[%d]->mRadioIndication == NULL",
6482                slotId);
6483    }
6484
6485    return 0;
6486}
6487
6488uint8_t hexCharToInt(uint8_t c) {
6489    if (c >= '0' && c <= '9') return (c - '0');
6490    if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
6491    if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
6492
6493    return INVALID_HEX_CHAR;
6494}
6495
6496uint8_t * convertHexStringToBytes(void *response, size_t responseLen) {
6497    if (responseLen % 2 != 0) {
6498        return NULL;
6499    }
6500
6501    uint8_t *bytes = (uint8_t *)calloc(responseLen/2, sizeof(uint8_t));
6502    if (bytes == NULL) {
6503        RLOGE("convertHexStringToBytes: cannot allocate memory for bytes string");
6504        return NULL;
6505    }
6506    uint8_t *hexString = (uint8_t *)response;
6507
6508    for (size_t i = 0; i < responseLen; i += 2) {
6509        uint8_t hexChar1 = hexCharToInt(hexString[i]);
6510        uint8_t hexChar2 = hexCharToInt(hexString[i + 1]);
6511
6512        if (hexChar1 == INVALID_HEX_CHAR || hexChar2 == INVALID_HEX_CHAR) {
6513            RLOGE("convertHexStringToBytes: invalid hex char %d %d",
6514                    hexString[i], hexString[i + 1]);
6515            free(bytes);
6516            return NULL;
6517        }
6518        bytes[i/2] = ((hexChar1 << 4) | hexChar2);
6519    }
6520
6521    return bytes;
6522}
6523
6524int radio::newSmsInd(int slotId, int indicationType,
6525                     int token, RIL_Errno e, void *response, size_t responseLen) {
6526    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6527        if (response == NULL || responseLen == 0) {
6528            RLOGE("newSmsInd: invalid response");
6529            return 0;
6530        }
6531
6532        uint8_t *bytes = convertHexStringToBytes(response, responseLen);
6533        if (bytes == NULL) {
6534            RLOGE("newSmsInd: convertHexStringToBytes failed");
6535            return 0;
6536        }
6537
6538        hidl_vec<uint8_t> pdu;
6539        pdu.setToExternal(bytes, responseLen/2);
6540#if VDBG
6541        RLOGD("newSmsInd");
6542#endif
6543        Return<void> retStatus = radioService[slotId]->mRadioIndication->newSms(
6544                convertIntToRadioIndicationType(indicationType), pdu);
6545        radioService[slotId]->checkReturnStatus(retStatus);
6546        free(bytes);
6547    } else {
6548        RLOGE("newSmsInd: radioService[%d]->mRadioIndication == NULL", slotId);
6549    }
6550
6551    return 0;
6552}
6553
6554int radio::newSmsStatusReportInd(int slotId,
6555                                 int indicationType, int token, RIL_Errno e, void *response,
6556                                 size_t responseLen) {
6557    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6558        if (response == NULL || responseLen == 0) {
6559            RLOGE("newSmsStatusReportInd: invalid response");
6560            return 0;
6561        }
6562
6563        uint8_t *bytes = convertHexStringToBytes(response, responseLen);
6564        if (bytes == NULL) {
6565            RLOGE("newSmsStatusReportInd: convertHexStringToBytes failed");
6566            return 0;
6567        }
6568
6569        hidl_vec<uint8_t> pdu;
6570        pdu.setToExternal(bytes, responseLen/2);
6571#if VDBG
6572        RLOGD("newSmsStatusReportInd");
6573#endif
6574        Return<void> retStatus = radioService[slotId]->mRadioIndication->newSmsStatusReport(
6575                convertIntToRadioIndicationType(indicationType), pdu);
6576        radioService[slotId]->checkReturnStatus(retStatus);
6577        free(bytes);
6578    } else {
6579        RLOGE("newSmsStatusReportInd: radioService[%d]->mRadioIndication == NULL", slotId);
6580    }
6581
6582    return 0;
6583}
6584
6585int radio::newSmsOnSimInd(int slotId, int indicationType,
6586                          int token, RIL_Errno e, void *response, size_t responseLen) {
6587    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6588        if (response == NULL || responseLen != sizeof(int)) {
6589            RLOGE("newSmsOnSimInd: invalid response");
6590            return 0;
6591        }
6592        int32_t recordNumber = ((int32_t *) response)[0];
6593#if VDBG
6594        RLOGD("newSmsOnSimInd: slotIndex %d", recordNumber);
6595#endif
6596        Return<void> retStatus = radioService[slotId]->mRadioIndication->newSmsOnSim(
6597                convertIntToRadioIndicationType(indicationType), recordNumber);
6598        radioService[slotId]->checkReturnStatus(retStatus);
6599    } else {
6600        RLOGE("newSmsOnSimInd: radioService[%d]->mRadioIndication == NULL", slotId);
6601    }
6602
6603    return 0;
6604}
6605
6606int radio::onUssdInd(int slotId, int indicationType,
6607                     int token, RIL_Errno e, void *response, size_t responseLen) {
6608    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6609        if (response == NULL || responseLen != 2 * sizeof(char *)) {
6610            RLOGE("onUssdInd: invalid response");
6611            return 0;
6612        }
6613        char **strings = (char **) response;
6614        char *mode = strings[0];
6615        hidl_string msg = convertCharPtrToHidlString(strings[1]);
6616        UssdModeType modeType = (UssdModeType) atoi(mode);
6617#if VDBG
6618        RLOGD("onUssdInd: mode %s", mode);
6619#endif
6620        Return<void> retStatus = radioService[slotId]->mRadioIndication->onUssd(
6621                convertIntToRadioIndicationType(indicationType), modeType, msg);
6622        radioService[slotId]->checkReturnStatus(retStatus);
6623    } else {
6624        RLOGE("onUssdInd: radioService[%d]->mRadioIndication == NULL", slotId);
6625    }
6626
6627    return 0;
6628}
6629
6630int radio::nitzTimeReceivedInd(int slotId,
6631                               int indicationType, int token, RIL_Errno e, void *response,
6632                               size_t responseLen) {
6633    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6634        if (response == NULL || responseLen == 0) {
6635            RLOGE("nitzTimeReceivedInd: invalid response");
6636            return 0;
6637        }
6638        hidl_string nitzTime = convertCharPtrToHidlString((char *) response);
6639        int64_t timeReceived = android::elapsedRealtime();
6640#if VDBG
6641        RLOGD("nitzTimeReceivedInd: nitzTime %s receivedTime %" PRId64, nitzTime.c_str(),
6642                timeReceived);
6643#endif
6644        Return<void> retStatus = radioService[slotId]->mRadioIndication->nitzTimeReceived(
6645                convertIntToRadioIndicationType(indicationType), nitzTime, timeReceived);
6646        radioService[slotId]->checkReturnStatus(retStatus);
6647    } else {
6648        RLOGE("nitzTimeReceivedInd: radioService[%d]->mRadioIndication == NULL", slotId);
6649        return -1;
6650    }
6651
6652    return 0;
6653}
6654
6655void convertRilSignalStrengthToHal(void *response, size_t responseLen,
6656        SignalStrength& signalStrength) {
6657    RIL_SignalStrength_v10 *rilSignalStrength = (RIL_SignalStrength_v10 *) response;
6658
6659    // Fixup LTE for backwards compatibility
6660    // signalStrength: -1 -> 99
6661    if (rilSignalStrength->LTE_SignalStrength.signalStrength == -1) {
6662        rilSignalStrength->LTE_SignalStrength.signalStrength = 99;
6663    }
6664    // rsrp: -1 -> INT_MAX all other negative value to positive.
6665    // So remap here
6666    if (rilSignalStrength->LTE_SignalStrength.rsrp == -1) {
6667        rilSignalStrength->LTE_SignalStrength.rsrp = INT_MAX;
6668    } else if (rilSignalStrength->LTE_SignalStrength.rsrp < -1) {
6669        rilSignalStrength->LTE_SignalStrength.rsrp = -rilSignalStrength->LTE_SignalStrength.rsrp;
6670    }
6671    // rsrq: -1 -> INT_MAX
6672    if (rilSignalStrength->LTE_SignalStrength.rsrq == -1) {
6673        rilSignalStrength->LTE_SignalStrength.rsrq = INT_MAX;
6674    }
6675    // Not remapping rssnr is already using INT_MAX
6676    // cqi: -1 -> INT_MAX
6677    if (rilSignalStrength->LTE_SignalStrength.cqi == -1) {
6678        rilSignalStrength->LTE_SignalStrength.cqi = INT_MAX;
6679    }
6680
6681    signalStrength.gw.signalStrength = rilSignalStrength->GW_SignalStrength.signalStrength;
6682    signalStrength.gw.bitErrorRate = rilSignalStrength->GW_SignalStrength.bitErrorRate;
6683    signalStrength.cdma.dbm = rilSignalStrength->CDMA_SignalStrength.dbm;
6684    signalStrength.cdma.ecio = rilSignalStrength->CDMA_SignalStrength.ecio;
6685    signalStrength.evdo.dbm = rilSignalStrength->EVDO_SignalStrength.dbm;
6686    signalStrength.evdo.ecio = rilSignalStrength->EVDO_SignalStrength.ecio;
6687    signalStrength.evdo.signalNoiseRatio =
6688            rilSignalStrength->EVDO_SignalStrength.signalNoiseRatio;
6689    signalStrength.lte.signalStrength = rilSignalStrength->LTE_SignalStrength.signalStrength;
6690    signalStrength.lte.rsrp = rilSignalStrength->LTE_SignalStrength.rsrp;
6691    signalStrength.lte.rsrq = rilSignalStrength->LTE_SignalStrength.rsrq;
6692    signalStrength.lte.rssnr = rilSignalStrength->LTE_SignalStrength.rssnr;
6693    signalStrength.lte.cqi = rilSignalStrength->LTE_SignalStrength.cqi;
6694    signalStrength.lte.timingAdvance = rilSignalStrength->LTE_SignalStrength.timingAdvance;
6695    signalStrength.tdScdma.rscp = rilSignalStrength->TD_SCDMA_SignalStrength.rscp;
6696}
6697
6698int radio::currentSignalStrengthInd(int slotId,
6699                                    int indicationType, int token, RIL_Errno e,
6700                                    void *response, size_t responseLen) {
6701    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6702        if (response == NULL || responseLen != sizeof(RIL_SignalStrength_v10)) {
6703            RLOGE("currentSignalStrengthInd: invalid response");
6704            return 0;
6705        }
6706
6707        SignalStrength signalStrength = {};
6708        convertRilSignalStrengthToHal(response, responseLen, signalStrength);
6709
6710#if VDBG
6711        RLOGD("currentSignalStrengthInd");
6712#endif
6713        Return<void> retStatus = radioService[slotId]->mRadioIndication->currentSignalStrength(
6714                convertIntToRadioIndicationType(indicationType), signalStrength);
6715        radioService[slotId]->checkReturnStatus(retStatus);
6716    } else {
6717        RLOGE("currentSignalStrengthInd: radioService[%d]->mRadioIndication == NULL",
6718                slotId);
6719    }
6720
6721    return 0;
6722}
6723
6724void convertRilDataCallToHal(RIL_Data_Call_Response_v11 *dcResponse,
6725        SetupDataCallResult& dcResult) {
6726    dcResult.status = (DataCallFailCause) dcResponse->status;
6727    dcResult.suggestedRetryTime = dcResponse->suggestedRetryTime;
6728    dcResult.cid = dcResponse->cid;
6729    dcResult.active = dcResponse->active;
6730    dcResult.type = convertCharPtrToHidlString(dcResponse->type);
6731    dcResult.ifname = convertCharPtrToHidlString(dcResponse->ifname);
6732    dcResult.addresses = convertCharPtrToHidlString(dcResponse->addresses);
6733    dcResult.dnses = convertCharPtrToHidlString(dcResponse->dnses);
6734    dcResult.gateways = convertCharPtrToHidlString(dcResponse->gateways);
6735    dcResult.pcscf = convertCharPtrToHidlString(dcResponse->pcscf);
6736    dcResult.mtu = dcResponse->mtu;
6737}
6738
6739void convertRilDataCallListToHal(void *response, size_t responseLen,
6740        hidl_vec<SetupDataCallResult>& dcResultList) {
6741    int num = responseLen / sizeof(RIL_Data_Call_Response_v11);
6742
6743    RIL_Data_Call_Response_v11 *dcResponse = (RIL_Data_Call_Response_v11 *) response;
6744    dcResultList.resize(num);
6745    for (int i = 0; i < num; i++) {
6746        convertRilDataCallToHal(&dcResponse[i], dcResultList[i]);
6747    }
6748}
6749
6750int radio::dataCallListChangedInd(int slotId,
6751                                  int indicationType, int token, RIL_Errno e, void *response,
6752                                  size_t responseLen) {
6753    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6754        if ((response == NULL && responseLen != 0)
6755                || responseLen % sizeof(RIL_Data_Call_Response_v11) != 0) {
6756            RLOGE("dataCallListChangedInd: invalid response");
6757            return 0;
6758        }
6759        hidl_vec<SetupDataCallResult> dcList;
6760        convertRilDataCallListToHal(response, responseLen, dcList);
6761#if VDBG
6762        RLOGD("dataCallListChangedInd");
6763#endif
6764        Return<void> retStatus = radioService[slotId]->mRadioIndication->dataCallListChanged(
6765                convertIntToRadioIndicationType(indicationType), dcList);
6766        radioService[slotId]->checkReturnStatus(retStatus);
6767    } else {
6768        RLOGE("dataCallListChangedInd: radioService[%d]->mRadioIndication == NULL", slotId);
6769    }
6770
6771    return 0;
6772}
6773
6774int radio::suppSvcNotifyInd(int slotId, int indicationType,
6775                            int token, RIL_Errno e, void *response, size_t responseLen) {
6776    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6777        if (response == NULL || responseLen != sizeof(RIL_SuppSvcNotification)) {
6778            RLOGE("suppSvcNotifyInd: invalid response");
6779            return 0;
6780        }
6781
6782        SuppSvcNotification suppSvc = {};
6783        RIL_SuppSvcNotification *ssn = (RIL_SuppSvcNotification *) response;
6784        suppSvc.isMT = ssn->notificationType;
6785        suppSvc.code = ssn->code;
6786        suppSvc.index = ssn->index;
6787        suppSvc.type = ssn->type;
6788        suppSvc.number = convertCharPtrToHidlString(ssn->number);
6789
6790#if VDBG
6791        RLOGD("suppSvcNotifyInd: isMT %d code %d index %d type %d",
6792                suppSvc.isMT, suppSvc.code, suppSvc.index, suppSvc.type);
6793#endif
6794        Return<void> retStatus = radioService[slotId]->mRadioIndication->suppSvcNotify(
6795                convertIntToRadioIndicationType(indicationType), suppSvc);
6796        radioService[slotId]->checkReturnStatus(retStatus);
6797    } else {
6798        RLOGE("suppSvcNotifyInd: radioService[%d]->mRadioIndication == NULL", slotId);
6799    }
6800
6801    return 0;
6802}
6803
6804int radio::stkSessionEndInd(int slotId, int indicationType,
6805                            int token, RIL_Errno e, void *response, size_t responseLen) {
6806    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6807#if VDBG
6808        RLOGD("stkSessionEndInd");
6809#endif
6810        Return<void> retStatus = radioService[slotId]->mRadioIndication->stkSessionEnd(
6811                convertIntToRadioIndicationType(indicationType));
6812        radioService[slotId]->checkReturnStatus(retStatus);
6813    } else {
6814        RLOGE("stkSessionEndInd: radioService[%d]->mRadioIndication == NULL", slotId);
6815    }
6816
6817    return 0;
6818}
6819
6820int radio::stkProactiveCommandInd(int slotId,
6821                                  int indicationType, int token, RIL_Errno e, void *response,
6822                                  size_t responseLen) {
6823    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6824        if (response == NULL || responseLen == 0) {
6825            RLOGE("stkProactiveCommandInd: invalid response");
6826            return 0;
6827        }
6828#if VDBG
6829        RLOGD("stkProactiveCommandInd");
6830#endif
6831        Return<void> retStatus = radioService[slotId]->mRadioIndication->stkProactiveCommand(
6832                convertIntToRadioIndicationType(indicationType),
6833                convertCharPtrToHidlString((char *) response));
6834        radioService[slotId]->checkReturnStatus(retStatus);
6835    } else {
6836        RLOGE("stkProactiveCommandInd: radioService[%d]->mRadioIndication == NULL", slotId);
6837    }
6838
6839    return 0;
6840}
6841
6842int radio::stkEventNotifyInd(int slotId, int indicationType,
6843                             int token, RIL_Errno e, void *response, size_t responseLen) {
6844    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6845        if (response == NULL || responseLen == 0) {
6846            RLOGE("stkEventNotifyInd: invalid response");
6847            return 0;
6848        }
6849#if VDBG
6850        RLOGD("stkEventNotifyInd");
6851#endif
6852        Return<void> retStatus = radioService[slotId]->mRadioIndication->stkEventNotify(
6853                convertIntToRadioIndicationType(indicationType),
6854                convertCharPtrToHidlString((char *) response));
6855        radioService[slotId]->checkReturnStatus(retStatus);
6856    } else {
6857        RLOGE("stkEventNotifyInd: radioService[%d]->mRadioIndication == NULL", slotId);
6858    }
6859
6860    return 0;
6861}
6862
6863int radio::stkCallSetupInd(int slotId, int indicationType,
6864                           int token, RIL_Errno e, void *response, size_t responseLen) {
6865    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6866        if (response == NULL || responseLen != sizeof(int)) {
6867            RLOGE("stkCallSetupInd: invalid response");
6868            return 0;
6869        }
6870        int32_t timeout = ((int32_t *) response)[0];
6871#if VDBG
6872        RLOGD("stkCallSetupInd: timeout %d", timeout);
6873#endif
6874        Return<void> retStatus = radioService[slotId]->mRadioIndication->stkCallSetup(
6875                convertIntToRadioIndicationType(indicationType), timeout);
6876        radioService[slotId]->checkReturnStatus(retStatus);
6877    } else {
6878        RLOGE("stkCallSetupInd: radioService[%d]->mRadioIndication == NULL", slotId);
6879    }
6880
6881    return 0;
6882}
6883
6884int radio::simSmsStorageFullInd(int slotId,
6885                                int indicationType, int token, RIL_Errno e, void *response,
6886                                size_t responseLen) {
6887    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6888#if VDBG
6889        RLOGD("simSmsStorageFullInd");
6890#endif
6891        Return<void> retStatus = radioService[slotId]->mRadioIndication->simSmsStorageFull(
6892                convertIntToRadioIndicationType(indicationType));
6893        radioService[slotId]->checkReturnStatus(retStatus);
6894    } else {
6895        RLOGE("simSmsStorageFullInd: radioService[%d]->mRadioIndication == NULL", slotId);
6896    }
6897
6898    return 0;
6899}
6900
6901int radio::simRefreshInd(int slotId, int indicationType,
6902                         int token, RIL_Errno e, void *response, size_t responseLen) {
6903    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6904        if (response == NULL || responseLen != sizeof(RIL_SimRefreshResponse_v7)) {
6905            RLOGE("simRefreshInd: invalid response");
6906            return 0;
6907        }
6908
6909        SimRefreshResult refreshResult = {};
6910        RIL_SimRefreshResponse_v7 *simRefreshResponse = ((RIL_SimRefreshResponse_v7 *) response);
6911        refreshResult.type =
6912                (android::hardware::radio::V1_0::SimRefreshType) simRefreshResponse->result;
6913        refreshResult.efId = simRefreshResponse->ef_id;
6914        refreshResult.aid = convertCharPtrToHidlString(simRefreshResponse->aid);
6915
6916#if VDBG
6917        RLOGD("simRefreshInd: type %d efId %d", refreshResult.type, refreshResult.efId);
6918#endif
6919        Return<void> retStatus = radioService[slotId]->mRadioIndication->simRefresh(
6920                convertIntToRadioIndicationType(indicationType), refreshResult);
6921        radioService[slotId]->checkReturnStatus(retStatus);
6922    } else {
6923        RLOGE("simRefreshInd: radioService[%d]->mRadioIndication == NULL", slotId);
6924    }
6925
6926    return 0;
6927}
6928
6929void convertRilCdmaSignalInfoRecordToHal(RIL_CDMA_SignalInfoRecord *signalInfoRecord,
6930        CdmaSignalInfoRecord& record) {
6931    record.isPresent = signalInfoRecord->isPresent;
6932    record.signalType = signalInfoRecord->signalType;
6933    record.alertPitch = signalInfoRecord->alertPitch;
6934    record.signal = signalInfoRecord->signal;
6935}
6936
6937int radio::callRingInd(int slotId, int indicationType,
6938                       int token, RIL_Errno e, void *response, size_t responseLen) {
6939    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6940        bool isGsm;
6941        CdmaSignalInfoRecord record = {};
6942        if (response == NULL || responseLen == 0) {
6943            isGsm = true;
6944        } else {
6945            isGsm = false;
6946            if (responseLen != sizeof (RIL_CDMA_SignalInfoRecord)) {
6947                RLOGE("callRingInd: invalid response");
6948                return 0;
6949            }
6950            convertRilCdmaSignalInfoRecordToHal((RIL_CDMA_SignalInfoRecord *) response, record);
6951        }
6952
6953#if VDBG
6954        RLOGD("callRingInd: isGsm %d", isGsm);
6955#endif
6956        Return<void> retStatus = radioService[slotId]->mRadioIndication->callRing(
6957                convertIntToRadioIndicationType(indicationType), isGsm, record);
6958        radioService[slotId]->checkReturnStatus(retStatus);
6959    } else {
6960        RLOGE("callRingInd: radioService[%d]->mRadioIndication == NULL", slotId);
6961    }
6962
6963    return 0;
6964}
6965
6966int radio::simStatusChangedInd(int slotId,
6967                               int indicationType, int token, RIL_Errno e, void *response,
6968                               size_t responseLen) {
6969    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6970#if VDBG
6971        RLOGD("simStatusChangedInd");
6972#endif
6973        Return<void> retStatus = radioService[slotId]->mRadioIndication->simStatusChanged(
6974                convertIntToRadioIndicationType(indicationType));
6975        radioService[slotId]->checkReturnStatus(retStatus);
6976    } else {
6977        RLOGE("simStatusChangedInd: radioService[%d]->mRadioIndication == NULL", slotId);
6978    }
6979
6980    return 0;
6981}
6982
6983int radio::cdmaNewSmsInd(int slotId, int indicationType,
6984                         int token, RIL_Errno e, void *response, size_t responseLen) {
6985    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
6986        if (response == NULL || responseLen != sizeof(RIL_CDMA_SMS_Message)) {
6987            RLOGE("cdmaNewSmsInd: invalid response");
6988            return 0;
6989        }
6990
6991        CdmaSmsMessage msg = {};
6992        RIL_CDMA_SMS_Message *rilMsg = (RIL_CDMA_SMS_Message *) response;
6993        msg.teleserviceId = rilMsg->uTeleserviceID;
6994        msg.isServicePresent = rilMsg->bIsServicePresent;
6995        msg.serviceCategory = rilMsg->uServicecategory;
6996        msg.address.digitMode =
6997                (android::hardware::radio::V1_0::CdmaSmsDigitMode) rilMsg->sAddress.digit_mode;
6998        msg.address.numberMode =
6999                (android::hardware::radio::V1_0::CdmaSmsNumberMode) rilMsg->sAddress.number_mode;
7000        msg.address.numberType =
7001                (android::hardware::radio::V1_0::CdmaSmsNumberType) rilMsg->sAddress.number_type;
7002        msg.address.numberPlan =
7003                (android::hardware::radio::V1_0::CdmaSmsNumberPlan) rilMsg->sAddress.number_plan;
7004
7005        int digitLimit = MIN((rilMsg->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
7006        msg.address.digits.setToExternal(rilMsg->sAddress.digits, digitLimit);
7007
7008        msg.subAddress.subaddressType = (android::hardware::radio::V1_0::CdmaSmsSubaddressType)
7009                rilMsg->sSubAddress.subaddressType;
7010        msg.subAddress.odd = rilMsg->sSubAddress.odd;
7011
7012        digitLimit= MIN((rilMsg->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
7013        msg.subAddress.digits.setToExternal(rilMsg->sSubAddress.digits, digitLimit);
7014
7015        digitLimit = MIN((rilMsg->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
7016        msg.bearerData.setToExternal(rilMsg->aBearerData, digitLimit);
7017
7018#if VDBG
7019        RLOGD("cdmaNewSmsInd");
7020#endif
7021        Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaNewSms(
7022                convertIntToRadioIndicationType(indicationType), msg);
7023        radioService[slotId]->checkReturnStatus(retStatus);
7024    } else {
7025        RLOGE("cdmaNewSmsInd: radioService[%d]->mRadioIndication == NULL", slotId);
7026    }
7027
7028    return 0;
7029}
7030
7031int radio::newBroadcastSmsInd(int slotId,
7032                              int indicationType, int token, RIL_Errno e, void *response,
7033                              size_t responseLen) {
7034    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7035        if (response == NULL || responseLen == 0) {
7036            RLOGE("newBroadcastSmsInd: invalid response");
7037            return 0;
7038        }
7039
7040        hidl_vec<uint8_t> data;
7041        data.setToExternal((uint8_t *) response, responseLen);
7042#if VDBG
7043        RLOGD("newBroadcastSmsInd");
7044#endif
7045        Return<void> retStatus = radioService[slotId]->mRadioIndication->newBroadcastSms(
7046                convertIntToRadioIndicationType(indicationType), data);
7047        radioService[slotId]->checkReturnStatus(retStatus);
7048    } else {
7049        RLOGE("newBroadcastSmsInd: radioService[%d]->mRadioIndication == NULL", slotId);
7050    }
7051
7052    return 0;
7053}
7054
7055int radio::cdmaRuimSmsStorageFullInd(int slotId,
7056                                     int indicationType, int token, RIL_Errno e, void *response,
7057                                     size_t responseLen) {
7058    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7059#if VDBG
7060        RLOGD("cdmaRuimSmsStorageFullInd");
7061#endif
7062        Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaRuimSmsStorageFull(
7063                convertIntToRadioIndicationType(indicationType));
7064        radioService[slotId]->checkReturnStatus(retStatus);
7065    } else {
7066        RLOGE("cdmaRuimSmsStorageFullInd: radioService[%d]->mRadioIndication == NULL",
7067                slotId);
7068    }
7069
7070    return 0;
7071}
7072
7073int radio::restrictedStateChangedInd(int slotId,
7074                                     int indicationType, int token, RIL_Errno e, void *response,
7075                                     size_t responseLen) {
7076    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7077        if (response == NULL || responseLen != sizeof(int)) {
7078            RLOGE("restrictedStateChangedInd: invalid response");
7079            return 0;
7080        }
7081        int32_t state = ((int32_t *) response)[0];
7082#if VDBG
7083        RLOGD("restrictedStateChangedInd: state %d", state);
7084#endif
7085        Return<void> retStatus = radioService[slotId]->mRadioIndication->restrictedStateChanged(
7086                convertIntToRadioIndicationType(indicationType), (PhoneRestrictedState) state);
7087        radioService[slotId]->checkReturnStatus(retStatus);
7088    } else {
7089        RLOGE("restrictedStateChangedInd: radioService[%d]->mRadioIndication == NULL",
7090                slotId);
7091    }
7092
7093    return 0;
7094}
7095
7096int radio::enterEmergencyCallbackModeInd(int slotId,
7097                                         int indicationType, int token, RIL_Errno e, void *response,
7098                                         size_t responseLen) {
7099    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7100#if VDBG
7101        RLOGD("enterEmergencyCallbackModeInd");
7102#endif
7103        Return<void> retStatus = radioService[slotId]->mRadioIndication->enterEmergencyCallbackMode(
7104                convertIntToRadioIndicationType(indicationType));
7105        radioService[slotId]->checkReturnStatus(retStatus);
7106    } else {
7107        RLOGE("enterEmergencyCallbackModeInd: radioService[%d]->mRadioIndication == NULL",
7108                slotId);
7109    }
7110
7111    return 0;
7112}
7113
7114int radio::cdmaCallWaitingInd(int slotId,
7115                              int indicationType, int token, RIL_Errno e, void *response,
7116                              size_t responseLen) {
7117    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7118        if (response == NULL || responseLen != sizeof(RIL_CDMA_CallWaiting_v6)) {
7119            RLOGE("cdmaCallWaitingInd: invalid response");
7120            return 0;
7121        }
7122
7123        CdmaCallWaiting callWaitingRecord = {};
7124        RIL_CDMA_CallWaiting_v6 *callWaitingRil = ((RIL_CDMA_CallWaiting_v6 *) response);
7125        callWaitingRecord.number = convertCharPtrToHidlString(callWaitingRil->number);
7126        callWaitingRecord.numberPresentation =
7127                (CdmaCallWaitingNumberPresentation) callWaitingRil->numberPresentation;
7128        callWaitingRecord.name = convertCharPtrToHidlString(callWaitingRil->name);
7129        convertRilCdmaSignalInfoRecordToHal(&callWaitingRil->signalInfoRecord,
7130                callWaitingRecord.signalInfoRecord);
7131        callWaitingRecord.numberType = (CdmaCallWaitingNumberType) callWaitingRil->number_type;
7132        callWaitingRecord.numberPlan = (CdmaCallWaitingNumberPlan) callWaitingRil->number_plan;
7133
7134#if VDBG
7135        RLOGD("cdmaCallWaitingInd");
7136#endif
7137        Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaCallWaiting(
7138                convertIntToRadioIndicationType(indicationType), callWaitingRecord);
7139        radioService[slotId]->checkReturnStatus(retStatus);
7140    } else {
7141        RLOGE("cdmaCallWaitingInd: radioService[%d]->mRadioIndication == NULL", slotId);
7142    }
7143
7144    return 0;
7145}
7146
7147int radio::cdmaOtaProvisionStatusInd(int slotId,
7148                                     int indicationType, int token, RIL_Errno e, void *response,
7149                                     size_t responseLen) {
7150    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7151        if (response == NULL || responseLen != sizeof(int)) {
7152            RLOGE("cdmaOtaProvisionStatusInd: invalid response");
7153            return 0;
7154        }
7155        int32_t status = ((int32_t *) response)[0];
7156#if VDBG
7157        RLOGD("cdmaOtaProvisionStatusInd: status %d", status);
7158#endif
7159        Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaOtaProvisionStatus(
7160                convertIntToRadioIndicationType(indicationType), (CdmaOtaProvisionStatus) status);
7161        radioService[slotId]->checkReturnStatus(retStatus);
7162    } else {
7163        RLOGE("cdmaOtaProvisionStatusInd: radioService[%d]->mRadioIndication == NULL",
7164                slotId);
7165    }
7166
7167    return 0;
7168}
7169
7170int radio::cdmaInfoRecInd(int slotId,
7171                          int indicationType, int token, RIL_Errno e, void *response,
7172                          size_t responseLen) {
7173    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7174        if (response == NULL || responseLen != sizeof(RIL_CDMA_InformationRecords)) {
7175            RLOGE("cdmaInfoRecInd: invalid response");
7176            return 0;
7177        }
7178
7179        CdmaInformationRecords records = {};
7180        RIL_CDMA_InformationRecords *recordsRil = (RIL_CDMA_InformationRecords *) response;
7181
7182        char* string8 = NULL;
7183        int num = MIN(recordsRil->numberOfInfoRecs, RIL_CDMA_MAX_NUMBER_OF_INFO_RECS);
7184        if (recordsRil->numberOfInfoRecs > RIL_CDMA_MAX_NUMBER_OF_INFO_RECS) {
7185            RLOGE("cdmaInfoRecInd: received %d recs which is more than %d, dropping "
7186                    "additional ones", recordsRil->numberOfInfoRecs,
7187                    RIL_CDMA_MAX_NUMBER_OF_INFO_RECS);
7188        }
7189        records.infoRec.resize(num);
7190        for (int i = 0 ; i < num ; i++) {
7191            CdmaInformationRecord *record = &records.infoRec[i];
7192            RIL_CDMA_InformationRecord *infoRec = &recordsRil->infoRec[i];
7193            record->name = (CdmaInfoRecName) infoRec->name;
7194            // All vectors should be size 0 except one which will be size 1. Set everything to
7195            // size 0 initially.
7196            record->display.resize(0);
7197            record->number.resize(0);
7198            record->signal.resize(0);
7199            record->redir.resize(0);
7200            record->lineCtrl.resize(0);
7201            record->clir.resize(0);
7202            record->audioCtrl.resize(0);
7203            switch (infoRec->name) {
7204                case RIL_CDMA_DISPLAY_INFO_REC:
7205                case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC: {
7206                    if (infoRec->rec.display.alpha_len > CDMA_ALPHA_INFO_BUFFER_LENGTH) {
7207                        RLOGE("cdmaInfoRecInd: invalid display info response length %d "
7208                                "expected not more than %d", (int) infoRec->rec.display.alpha_len,
7209                                CDMA_ALPHA_INFO_BUFFER_LENGTH);
7210                        return 0;
7211                    }
7212                    string8 = (char*) malloc((infoRec->rec.display.alpha_len + 1) * sizeof(char));
7213                    if (string8 == NULL) {
7214                        RLOGE("cdmaInfoRecInd: Memory allocation failed for "
7215                                "responseCdmaInformationRecords");
7216                        return 0;
7217                    }
7218                    memcpy(string8, infoRec->rec.display.alpha_buf, infoRec->rec.display.alpha_len);
7219                    string8[(int)infoRec->rec.display.alpha_len] = '\0';
7220
7221                    record->display.resize(1);
7222                    record->display[0].alphaBuf = string8;
7223                    free(string8);
7224                    string8 = NULL;
7225                    break;
7226                }
7227
7228                case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
7229                case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
7230                case RIL_CDMA_CONNECTED_NUMBER_INFO_REC: {
7231                    if (infoRec->rec.number.len > CDMA_NUMBER_INFO_BUFFER_LENGTH) {
7232                        RLOGE("cdmaInfoRecInd: invalid display info response length %d "
7233                                "expected not more than %d", (int) infoRec->rec.number.len,
7234                                CDMA_NUMBER_INFO_BUFFER_LENGTH);
7235                        return 0;
7236                    }
7237                    string8 = (char*) malloc((infoRec->rec.number.len + 1) * sizeof(char));
7238                    if (string8 == NULL) {
7239                        RLOGE("cdmaInfoRecInd: Memory allocation failed for "
7240                                "responseCdmaInformationRecords");
7241                        return 0;
7242                    }
7243                    memcpy(string8, infoRec->rec.number.buf, infoRec->rec.number.len);
7244                    string8[(int)infoRec->rec.number.len] = '\0';
7245
7246                    record->number.resize(1);
7247                    record->number[0].number = string8;
7248                    free(string8);
7249                    string8 = NULL;
7250                    record->number[0].numberType = infoRec->rec.number.number_type;
7251                    record->number[0].numberPlan = infoRec->rec.number.number_plan;
7252                    record->number[0].pi = infoRec->rec.number.pi;
7253                    record->number[0].si = infoRec->rec.number.si;
7254                    break;
7255                }
7256
7257                case RIL_CDMA_SIGNAL_INFO_REC: {
7258                    record->signal.resize(1);
7259                    record->signal[0].isPresent = infoRec->rec.signal.isPresent;
7260                    record->signal[0].signalType = infoRec->rec.signal.signalType;
7261                    record->signal[0].alertPitch = infoRec->rec.signal.alertPitch;
7262                    record->signal[0].signal = infoRec->rec.signal.signal;
7263                    break;
7264                }
7265
7266                case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC: {
7267                    if (infoRec->rec.redir.redirectingNumber.len >
7268                                                  CDMA_NUMBER_INFO_BUFFER_LENGTH) {
7269                        RLOGE("cdmaInfoRecInd: invalid display info response length %d "
7270                                "expected not more than %d\n",
7271                                (int)infoRec->rec.redir.redirectingNumber.len,
7272                                CDMA_NUMBER_INFO_BUFFER_LENGTH);
7273                        return 0;
7274                    }
7275                    string8 = (char*) malloc((infoRec->rec.redir.redirectingNumber.len + 1) *
7276                            sizeof(char));
7277                    if (string8 == NULL) {
7278                        RLOGE("cdmaInfoRecInd: Memory allocation failed for "
7279                                "responseCdmaInformationRecords");
7280                        return 0;
7281                    }
7282                    memcpy(string8, infoRec->rec.redir.redirectingNumber.buf,
7283                            infoRec->rec.redir.redirectingNumber.len);
7284                    string8[(int)infoRec->rec.redir.redirectingNumber.len] = '\0';
7285
7286                    record->redir.resize(1);
7287                    record->redir[0].redirectingNumber.number = string8;
7288                    free(string8);
7289                    string8 = NULL;
7290                    record->redir[0].redirectingNumber.numberType =
7291                            infoRec->rec.redir.redirectingNumber.number_type;
7292                    record->redir[0].redirectingNumber.numberPlan =
7293                            infoRec->rec.redir.redirectingNumber.number_plan;
7294                    record->redir[0].redirectingNumber.pi = infoRec->rec.redir.redirectingNumber.pi;
7295                    record->redir[0].redirectingNumber.si = infoRec->rec.redir.redirectingNumber.si;
7296                    record->redir[0].redirectingReason =
7297                            (CdmaRedirectingReason) infoRec->rec.redir.redirectingReason;
7298                    break;
7299                }
7300
7301                case RIL_CDMA_LINE_CONTROL_INFO_REC: {
7302                    record->lineCtrl.resize(1);
7303                    record->lineCtrl[0].lineCtrlPolarityIncluded =
7304                            infoRec->rec.lineCtrl.lineCtrlPolarityIncluded;
7305                    record->lineCtrl[0].lineCtrlToggle = infoRec->rec.lineCtrl.lineCtrlToggle;
7306                    record->lineCtrl[0].lineCtrlReverse = infoRec->rec.lineCtrl.lineCtrlReverse;
7307                    record->lineCtrl[0].lineCtrlPowerDenial =
7308                            infoRec->rec.lineCtrl.lineCtrlPowerDenial;
7309                    break;
7310                }
7311
7312                case RIL_CDMA_T53_CLIR_INFO_REC: {
7313                    record->clir.resize(1);
7314                    record->clir[0].cause = infoRec->rec.clir.cause;
7315                    break;
7316                }
7317
7318                case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC: {
7319                    record->audioCtrl.resize(1);
7320                    record->audioCtrl[0].upLink = infoRec->rec.audioCtrl.upLink;
7321                    record->audioCtrl[0].downLink = infoRec->rec.audioCtrl.downLink;
7322                    break;
7323                }
7324
7325                case RIL_CDMA_T53_RELEASE_INFO_REC:
7326                    RLOGE("cdmaInfoRecInd: RIL_CDMA_T53_RELEASE_INFO_REC: INVALID");
7327                    return 0;
7328
7329                default:
7330                    RLOGE("cdmaInfoRecInd: Incorrect name value");
7331                    return 0;
7332            }
7333        }
7334
7335#if VDBG
7336        RLOGD("cdmaInfoRecInd");
7337#endif
7338        Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaInfoRec(
7339                convertIntToRadioIndicationType(indicationType), records);
7340        radioService[slotId]->checkReturnStatus(retStatus);
7341    } else {
7342        RLOGE("cdmaInfoRecInd: radioService[%d]->mRadioIndication == NULL", slotId);
7343    }
7344
7345    return 0;
7346}
7347
7348int radio::indicateRingbackToneInd(int slotId,
7349                                   int indicationType, int token, RIL_Errno e, void *response,
7350                                   size_t responseLen) {
7351    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7352        if (response == NULL || responseLen != sizeof(int)) {
7353            RLOGE("indicateRingbackToneInd: invalid response");
7354            return 0;
7355        }
7356        bool start = ((int32_t *) response)[0];
7357#if VDBG
7358        RLOGD("indicateRingbackToneInd: start %d", start);
7359#endif
7360        Return<void> retStatus = radioService[slotId]->mRadioIndication->indicateRingbackTone(
7361                convertIntToRadioIndicationType(indicationType), start);
7362        radioService[slotId]->checkReturnStatus(retStatus);
7363    } else {
7364        RLOGE("indicateRingbackToneInd: radioService[%d]->mRadioIndication == NULL", slotId);
7365    }
7366
7367    return 0;
7368}
7369
7370int radio::resendIncallMuteInd(int slotId,
7371                               int indicationType, int token, RIL_Errno e, void *response,
7372                               size_t responseLen) {
7373    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7374#if VDBG
7375        RLOGD("resendIncallMuteInd");
7376#endif
7377        Return<void> retStatus = radioService[slotId]->mRadioIndication->resendIncallMute(
7378                convertIntToRadioIndicationType(indicationType));
7379        radioService[slotId]->checkReturnStatus(retStatus);
7380    } else {
7381        RLOGE("resendIncallMuteInd: radioService[%d]->mRadioIndication == NULL", slotId);
7382    }
7383
7384    return 0;
7385}
7386
7387int radio::cdmaSubscriptionSourceChangedInd(int slotId,
7388                                            int indicationType, int token, RIL_Errno e,
7389                                            void *response, size_t responseLen) {
7390    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7391        if (response == NULL || responseLen != sizeof(int)) {
7392            RLOGE("cdmaSubscriptionSourceChangedInd: invalid response");
7393            return 0;
7394        }
7395        int32_t cdmaSource = ((int32_t *) response)[0];
7396#if VDBG
7397        RLOGD("cdmaSubscriptionSourceChangedInd: cdmaSource %d", cdmaSource);
7398#endif
7399        Return<void> retStatus = radioService[slotId]->mRadioIndication->
7400                cdmaSubscriptionSourceChanged(convertIntToRadioIndicationType(indicationType),
7401                (CdmaSubscriptionSource) cdmaSource);
7402        radioService[slotId]->checkReturnStatus(retStatus);
7403    } else {
7404        RLOGE("cdmaSubscriptionSourceChangedInd: radioService[%d]->mRadioIndication == NULL",
7405                slotId);
7406    }
7407
7408    return 0;
7409}
7410
7411int radio::cdmaPrlChangedInd(int slotId,
7412                             int indicationType, int token, RIL_Errno e, void *response,
7413                             size_t responseLen) {
7414    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7415        if (response == NULL || responseLen != sizeof(int)) {
7416            RLOGE("cdmaPrlChangedInd: invalid response");
7417            return 0;
7418        }
7419        int32_t version = ((int32_t *) response)[0];
7420#if VDBG
7421        RLOGD("cdmaPrlChangedInd: version %d", version);
7422#endif
7423        Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaPrlChanged(
7424                convertIntToRadioIndicationType(indicationType), version);
7425        radioService[slotId]->checkReturnStatus(retStatus);
7426    } else {
7427        RLOGE("cdmaPrlChangedInd: radioService[%d]->mRadioIndication == NULL", slotId);
7428    }
7429
7430    return 0;
7431}
7432
7433int radio::exitEmergencyCallbackModeInd(int slotId,
7434                                        int indicationType, int token, RIL_Errno e, void *response,
7435                                        size_t responseLen) {
7436    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7437#if VDBG
7438        RLOGD("exitEmergencyCallbackModeInd");
7439#endif
7440        Return<void> retStatus = radioService[slotId]->mRadioIndication->exitEmergencyCallbackMode(
7441                convertIntToRadioIndicationType(indicationType));
7442        radioService[slotId]->checkReturnStatus(retStatus);
7443    } else {
7444        RLOGE("exitEmergencyCallbackModeInd: radioService[%d]->mRadioIndication == NULL",
7445                slotId);
7446    }
7447
7448    return 0;
7449}
7450
7451int radio::rilConnectedInd(int slotId,
7452                           int indicationType, int token, RIL_Errno e, void *response,
7453                           size_t responseLen) {
7454    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7455        RLOGD("rilConnectedInd");
7456        Return<void> retStatus = radioService[slotId]->mRadioIndication->rilConnected(
7457                convertIntToRadioIndicationType(indicationType));
7458        radioService[slotId]->checkReturnStatus(retStatus);
7459    } else {
7460        RLOGE("rilConnectedInd: radioService[%d]->mRadioIndication == NULL", slotId);
7461    }
7462
7463    return 0;
7464}
7465
7466int radio::voiceRadioTechChangedInd(int slotId,
7467                                    int indicationType, int token, RIL_Errno e, void *response,
7468                                    size_t responseLen) {
7469    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7470        if (response == NULL || responseLen != sizeof(int)) {
7471            RLOGE("voiceRadioTechChangedInd: invalid response");
7472            return 0;
7473        }
7474        int32_t rat = ((int32_t *) response)[0];
7475#if VDBG
7476        RLOGD("voiceRadioTechChangedInd: rat %d", rat);
7477#endif
7478        Return<void> retStatus = radioService[slotId]->mRadioIndication->voiceRadioTechChanged(
7479                convertIntToRadioIndicationType(indicationType), (RadioTechnology) rat);
7480        radioService[slotId]->checkReturnStatus(retStatus);
7481    } else {
7482        RLOGE("voiceRadioTechChangedInd: radioService[%d]->mRadioIndication == NULL",
7483                slotId);
7484    }
7485
7486    return 0;
7487}
7488
7489void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec<CellInfo>& records) {
7490    int num = responseLen / sizeof(RIL_CellInfo_v12);
7491    records.resize(num);
7492
7493    RIL_CellInfo_v12 *rillCellInfo = (RIL_CellInfo_v12 *) response;
7494    for (int i = 0; i < num; i++) {
7495        records[i].cellInfoType = (CellInfoType) rillCellInfo->cellInfoType;
7496        records[i].registered = rillCellInfo->registered;
7497        records[i].timeStampType = (TimeStampType) rillCellInfo->timeStampType;
7498        records[i].timeStamp = rillCellInfo->timeStamp;
7499        // All vectors should be size 0 except one which will be size 1. Set everything to
7500        // size 0 initially.
7501        records[i].gsm.resize(0);
7502        records[i].wcdma.resize(0);
7503        records[i].cdma.resize(0);
7504        records[i].lte.resize(0);
7505        records[i].tdscdma.resize(0);
7506        switch(rillCellInfo->cellInfoType) {
7507            case RIL_CELL_INFO_TYPE_GSM: {
7508                records[i].gsm.resize(1);
7509                CellInfoGsm *cellInfoGsm = &records[i].gsm[0];
7510                cellInfoGsm->cellIdentityGsm.mcc =
7511                        std::to_string(rillCellInfo->CellInfo.gsm.cellIdentityGsm.mcc);
7512                cellInfoGsm->cellIdentityGsm.mnc =
7513                        std::to_string(rillCellInfo->CellInfo.gsm.cellIdentityGsm.mnc);
7514                cellInfoGsm->cellIdentityGsm.lac =
7515                        rillCellInfo->CellInfo.gsm.cellIdentityGsm.lac;
7516                cellInfoGsm->cellIdentityGsm.cid =
7517                        rillCellInfo->CellInfo.gsm.cellIdentityGsm.cid;
7518                cellInfoGsm->cellIdentityGsm.arfcn =
7519                        rillCellInfo->CellInfo.gsm.cellIdentityGsm.arfcn;
7520                cellInfoGsm->cellIdentityGsm.bsic =
7521                        rillCellInfo->CellInfo.gsm.cellIdentityGsm.bsic;
7522                cellInfoGsm->signalStrengthGsm.signalStrength =
7523                        rillCellInfo->CellInfo.gsm.signalStrengthGsm.signalStrength;
7524                cellInfoGsm->signalStrengthGsm.bitErrorRate =
7525                        rillCellInfo->CellInfo.gsm.signalStrengthGsm.bitErrorRate;
7526                cellInfoGsm->signalStrengthGsm.timingAdvance =
7527                        rillCellInfo->CellInfo.gsm.signalStrengthGsm.timingAdvance;
7528                break;
7529            }
7530
7531            case RIL_CELL_INFO_TYPE_WCDMA: {
7532                records[i].wcdma.resize(1);
7533                CellInfoWcdma *cellInfoWcdma = &records[i].wcdma[0];
7534                cellInfoWcdma->cellIdentityWcdma.mcc =
7535                        std::to_string(rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.mcc);
7536                cellInfoWcdma->cellIdentityWcdma.mnc =
7537                        std::to_string(rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.mnc);
7538                cellInfoWcdma->cellIdentityWcdma.lac =
7539                        rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.lac;
7540                cellInfoWcdma->cellIdentityWcdma.cid =
7541                        rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.cid;
7542                cellInfoWcdma->cellIdentityWcdma.psc =
7543                        rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.psc;
7544                cellInfoWcdma->cellIdentityWcdma.uarfcn =
7545                        rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.uarfcn;
7546                cellInfoWcdma->signalStrengthWcdma.signalStrength =
7547                        rillCellInfo->CellInfo.wcdma.signalStrengthWcdma.signalStrength;
7548                cellInfoWcdma->signalStrengthWcdma.bitErrorRate =
7549                        rillCellInfo->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate;
7550                break;
7551            }
7552
7553            case RIL_CELL_INFO_TYPE_CDMA: {
7554                records[i].cdma.resize(1);
7555                CellInfoCdma *cellInfoCdma = &records[i].cdma[0];
7556                cellInfoCdma->cellIdentityCdma.networkId =
7557                        rillCellInfo->CellInfo.cdma.cellIdentityCdma.networkId;
7558                cellInfoCdma->cellIdentityCdma.systemId =
7559                        rillCellInfo->CellInfo.cdma.cellIdentityCdma.systemId;
7560                cellInfoCdma->cellIdentityCdma.baseStationId =
7561                        rillCellInfo->CellInfo.cdma.cellIdentityCdma.basestationId;
7562                cellInfoCdma->cellIdentityCdma.longitude =
7563                        rillCellInfo->CellInfo.cdma.cellIdentityCdma.longitude;
7564                cellInfoCdma->cellIdentityCdma.latitude =
7565                        rillCellInfo->CellInfo.cdma.cellIdentityCdma.latitude;
7566                cellInfoCdma->signalStrengthCdma.dbm =
7567                        rillCellInfo->CellInfo.cdma.signalStrengthCdma.dbm;
7568                cellInfoCdma->signalStrengthCdma.ecio =
7569                        rillCellInfo->CellInfo.cdma.signalStrengthCdma.ecio;
7570                cellInfoCdma->signalStrengthEvdo.dbm =
7571                        rillCellInfo->CellInfo.cdma.signalStrengthEvdo.dbm;
7572                cellInfoCdma->signalStrengthEvdo.ecio =
7573                        rillCellInfo->CellInfo.cdma.signalStrengthEvdo.ecio;
7574                cellInfoCdma->signalStrengthEvdo.signalNoiseRatio =
7575                        rillCellInfo->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio;
7576                break;
7577            }
7578
7579            case RIL_CELL_INFO_TYPE_LTE: {
7580                records[i].lte.resize(1);
7581                CellInfoLte *cellInfoLte = &records[i].lte[0];
7582                cellInfoLte->cellIdentityLte.mcc =
7583                        std::to_string(rillCellInfo->CellInfo.lte.cellIdentityLte.mcc);
7584                cellInfoLte->cellIdentityLte.mnc =
7585                        std::to_string(rillCellInfo->CellInfo.lte.cellIdentityLte.mnc);
7586                cellInfoLte->cellIdentityLte.ci =
7587                        rillCellInfo->CellInfo.lte.cellIdentityLte.ci;
7588                cellInfoLte->cellIdentityLte.pci =
7589                        rillCellInfo->CellInfo.lte.cellIdentityLte.pci;
7590                cellInfoLte->cellIdentityLte.tac =
7591                        rillCellInfo->CellInfo.lte.cellIdentityLte.tac;
7592                cellInfoLte->cellIdentityLte.earfcn =
7593                        rillCellInfo->CellInfo.lte.cellIdentityLte.earfcn;
7594                cellInfoLte->signalStrengthLte.signalStrength =
7595                        rillCellInfo->CellInfo.lte.signalStrengthLte.signalStrength;
7596                cellInfoLte->signalStrengthLte.rsrp =
7597                        rillCellInfo->CellInfo.lte.signalStrengthLte.rsrp;
7598                cellInfoLte->signalStrengthLte.rsrq =
7599                        rillCellInfo->CellInfo.lte.signalStrengthLte.rsrq;
7600                cellInfoLte->signalStrengthLte.rssnr =
7601                        rillCellInfo->CellInfo.lte.signalStrengthLte.rssnr;
7602                cellInfoLte->signalStrengthLte.cqi =
7603                        rillCellInfo->CellInfo.lte.signalStrengthLte.cqi;
7604                cellInfoLte->signalStrengthLte.timingAdvance =
7605                        rillCellInfo->CellInfo.lte.signalStrengthLte.timingAdvance;
7606                break;
7607            }
7608
7609            case RIL_CELL_INFO_TYPE_TD_SCDMA: {
7610                records[i].tdscdma.resize(1);
7611                CellInfoTdscdma *cellInfoTdscdma = &records[i].tdscdma[0];
7612                cellInfoTdscdma->cellIdentityTdscdma.mcc =
7613                        std::to_string(rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.mcc);
7614                cellInfoTdscdma->cellIdentityTdscdma.mnc =
7615                        std::to_string(rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.mnc);
7616                cellInfoTdscdma->cellIdentityTdscdma.lac =
7617                        rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.lac;
7618                cellInfoTdscdma->cellIdentityTdscdma.cid =
7619                        rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.cid;
7620                cellInfoTdscdma->cellIdentityTdscdma.cpid =
7621                        rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.cpid;
7622                cellInfoTdscdma->signalStrengthTdscdma.rscp =
7623                        rillCellInfo->CellInfo.tdscdma.signalStrengthTdscdma.rscp;
7624                break;
7625            }
7626            default: {
7627                break;
7628            }
7629        }
7630        rillCellInfo += 1;
7631    }
7632}
7633
7634int radio::cellInfoListInd(int slotId,
7635                           int indicationType, int token, RIL_Errno e, void *response,
7636                           size_t responseLen) {
7637    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7638        if ((response == NULL && responseLen != 0) || responseLen % sizeof(RIL_CellInfo_v12) != 0) {
7639            RLOGE("cellInfoListInd: invalid response");
7640            return 0;
7641        }
7642
7643        hidl_vec<CellInfo> records;
7644        convertRilCellInfoListToHal(response, responseLen, records);
7645
7646#if VDBG
7647        RLOGD("cellInfoListInd");
7648#endif
7649        Return<void> retStatus = radioService[slotId]->mRadioIndication->cellInfoList(
7650                convertIntToRadioIndicationType(indicationType), records);
7651        radioService[slotId]->checkReturnStatus(retStatus);
7652    } else {
7653        RLOGE("cellInfoListInd: radioService[%d]->mRadioIndication == NULL", slotId);
7654    }
7655
7656    return 0;
7657}
7658
7659int radio::imsNetworkStateChangedInd(int slotId,
7660                                     int indicationType, int token, RIL_Errno e, void *response,
7661                                     size_t responseLen) {
7662    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7663#if VDBG
7664        RLOGD("imsNetworkStateChangedInd");
7665#endif
7666        Return<void> retStatus = radioService[slotId]->mRadioIndication->imsNetworkStateChanged(
7667                convertIntToRadioIndicationType(indicationType));
7668        radioService[slotId]->checkReturnStatus(retStatus);
7669    } else {
7670        RLOGE("imsNetworkStateChangedInd: radioService[%d]->mRadioIndication == NULL",
7671                slotId);
7672    }
7673
7674    return 0;
7675}
7676
7677int radio::subscriptionStatusChangedInd(int slotId,
7678                                        int indicationType, int token, RIL_Errno e, void *response,
7679                                        size_t responseLen) {
7680    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7681        if (response == NULL || responseLen != sizeof(int)) {
7682            RLOGE("subscriptionStatusChangedInd: invalid response");
7683            return 0;
7684        }
7685        bool activate = ((int32_t *) response)[0];
7686#if VDBG
7687        RLOGD("subscriptionStatusChangedInd: activate %d", activate);
7688#endif
7689        Return<void> retStatus = radioService[slotId]->mRadioIndication->subscriptionStatusChanged(
7690                convertIntToRadioIndicationType(indicationType), activate);
7691        radioService[slotId]->checkReturnStatus(retStatus);
7692    } else {
7693        RLOGE("subscriptionStatusChangedInd: radioService[%d]->mRadioIndication == NULL",
7694                slotId);
7695    }
7696
7697    return 0;
7698}
7699
7700int radio::srvccStateNotifyInd(int slotId,
7701                               int indicationType, int token, RIL_Errno e, void *response,
7702                               size_t responseLen) {
7703    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7704        if (response == NULL || responseLen != sizeof(int)) {
7705            RLOGE("srvccStateNotifyInd: invalid response");
7706            return 0;
7707        }
7708        int32_t state = ((int32_t *) response)[0];
7709#if VDBG
7710        RLOGD("srvccStateNotifyInd: rat %d", state);
7711#endif
7712        Return<void> retStatus = radioService[slotId]->mRadioIndication->srvccStateNotify(
7713                convertIntToRadioIndicationType(indicationType), (SrvccState) state);
7714        radioService[slotId]->checkReturnStatus(retStatus);
7715    } else {
7716        RLOGE("srvccStateNotifyInd: radioService[%d]->mRadioIndication == NULL", slotId);
7717    }
7718
7719    return 0;
7720}
7721
7722void convertRilHardwareConfigListToHal(void *response, size_t responseLen,
7723        hidl_vec<HardwareConfig>& records) {
7724    int num = responseLen / sizeof(RIL_HardwareConfig);
7725    records.resize(num);
7726
7727    RIL_HardwareConfig *rilHardwareConfig = (RIL_HardwareConfig *) response;
7728    for (int i = 0; i < num; i++) {
7729        records[i].type = (HardwareConfigType) rilHardwareConfig[i].type;
7730        records[i].uuid = convertCharPtrToHidlString(rilHardwareConfig[i].uuid);
7731        records[i].state = (HardwareConfigState) rilHardwareConfig[i].state;
7732        switch (rilHardwareConfig[i].type) {
7733            case RIL_HARDWARE_CONFIG_MODEM: {
7734                records[i].modem.resize(1);
7735                records[i].sim.resize(0);
7736                HardwareConfigModem *hwConfigModem = &records[i].modem[0];
7737                hwConfigModem->rat = rilHardwareConfig[i].cfg.modem.rat;
7738                hwConfigModem->maxVoice = rilHardwareConfig[i].cfg.modem.maxVoice;
7739                hwConfigModem->maxData = rilHardwareConfig[i].cfg.modem.maxData;
7740                hwConfigModem->maxStandby = rilHardwareConfig[i].cfg.modem.maxStandby;
7741                break;
7742            }
7743
7744            case RIL_HARDWARE_CONFIG_SIM: {
7745                records[i].sim.resize(1);
7746                records[i].modem.resize(0);
7747                records[i].sim[0].modemUuid =
7748                        convertCharPtrToHidlString(rilHardwareConfig[i].cfg.sim.modemUuid);
7749                break;
7750            }
7751        }
7752    }
7753}
7754
7755int radio::hardwareConfigChangedInd(int slotId,
7756                                    int indicationType, int token, RIL_Errno e, void *response,
7757                                    size_t responseLen) {
7758    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7759        if ((response == NULL && responseLen != 0)
7760                || responseLen % sizeof(RIL_HardwareConfig) != 0) {
7761            RLOGE("hardwareConfigChangedInd: invalid response");
7762            return 0;
7763        }
7764
7765        hidl_vec<HardwareConfig> configs;
7766        convertRilHardwareConfigListToHal(response, responseLen, configs);
7767
7768#if VDBG
7769        RLOGD("hardwareConfigChangedInd");
7770#endif
7771        Return<void> retStatus = radioService[slotId]->mRadioIndication->hardwareConfigChanged(
7772                convertIntToRadioIndicationType(indicationType), configs);
7773        radioService[slotId]->checkReturnStatus(retStatus);
7774    } else {
7775        RLOGE("hardwareConfigChangedInd: radioService[%d]->mRadioIndication == NULL",
7776                slotId);
7777    }
7778
7779    return 0;
7780}
7781
7782void convertRilRadioCapabilityToHal(void *response, size_t responseLen, RadioCapability& rc) {
7783    RIL_RadioCapability *rilRadioCapability = (RIL_RadioCapability *) response;
7784    rc.session = rilRadioCapability->session;
7785    rc.phase = (android::hardware::radio::V1_0::RadioCapabilityPhase) rilRadioCapability->phase;
7786    rc.raf = rilRadioCapability->rat;
7787    rc.logicalModemUuid = convertCharPtrToHidlString(rilRadioCapability->logicalModemUuid);
7788    rc.status = (android::hardware::radio::V1_0::RadioCapabilityStatus) rilRadioCapability->status;
7789}
7790
7791int radio::radioCapabilityIndicationInd(int slotId,
7792                                        int indicationType, int token, RIL_Errno e, void *response,
7793                                        size_t responseLen) {
7794    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7795        if (response == NULL || responseLen != sizeof(RIL_RadioCapability)) {
7796            RLOGE("radioCapabilityIndicationInd: invalid response");
7797            return 0;
7798        }
7799
7800        RadioCapability rc = {};
7801        convertRilRadioCapabilityToHal(response, responseLen, rc);
7802
7803#if VDBG
7804        RLOGD("radioCapabilityIndicationInd");
7805#endif
7806        Return<void> retStatus = radioService[slotId]->mRadioIndication->radioCapabilityIndication(
7807                convertIntToRadioIndicationType(indicationType), rc);
7808        radioService[slotId]->checkReturnStatus(retStatus);
7809    } else {
7810        RLOGE("radioCapabilityIndicationInd: radioService[%d]->mRadioIndication == NULL",
7811                slotId);
7812    }
7813
7814    return 0;
7815}
7816
7817bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType) {
7818    if ((reqType == SS_INTERROGATION) &&
7819        (serType == SS_CFU ||
7820         serType == SS_CF_BUSY ||
7821         serType == SS_CF_NO_REPLY ||
7822         serType == SS_CF_NOT_REACHABLE ||
7823         serType == SS_CF_ALL ||
7824         serType == SS_CF_ALL_CONDITIONAL)) {
7825        return true;
7826    }
7827    return false;
7828}
7829
7830int radio::onSupplementaryServiceIndicationInd(int slotId,
7831                                               int indicationType, int token, RIL_Errno e,
7832                                               void *response, size_t responseLen) {
7833    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7834        if (response == NULL || responseLen != sizeof(RIL_StkCcUnsolSsResponse)) {
7835            RLOGE("onSupplementaryServiceIndicationInd: invalid response");
7836            return 0;
7837        }
7838
7839        RIL_StkCcUnsolSsResponse *rilSsResponse = (RIL_StkCcUnsolSsResponse *) response;
7840        StkCcUnsolSsResult ss = {};
7841        ss.serviceType = (SsServiceType) rilSsResponse->serviceType;
7842        ss.requestType = (SsRequestType) rilSsResponse->requestType;
7843        ss.teleserviceType = (SsTeleserviceType) rilSsResponse->teleserviceType;
7844        ss.serviceClass = rilSsResponse->serviceClass;
7845        ss.result = (RadioError) rilSsResponse->result;
7846
7847        if (isServiceTypeCfQuery(rilSsResponse->serviceType, rilSsResponse->requestType)) {
7848#if VDBG
7849            RLOGD("onSupplementaryServiceIndicationInd CF type, num of Cf elements %d",
7850                    rilSsResponse->cfData.numValidIndexes);
7851#endif
7852            if (rilSsResponse->cfData.numValidIndexes > NUM_SERVICE_CLASSES) {
7853                RLOGE("onSupplementaryServiceIndicationInd numValidIndexes is greater than "
7854                        "max value %d, truncating it to max value", NUM_SERVICE_CLASSES);
7855                rilSsResponse->cfData.numValidIndexes = NUM_SERVICE_CLASSES;
7856            }
7857
7858            ss.cfData.resize(1);
7859            ss.ssInfo.resize(0);
7860
7861            /* number of call info's */
7862            ss.cfData[0].cfInfo.resize(rilSsResponse->cfData.numValidIndexes);
7863
7864            for (int i = 0; i < rilSsResponse->cfData.numValidIndexes; i++) {
7865                 RIL_CallForwardInfo cf = rilSsResponse->cfData.cfInfo[i];
7866                 CallForwardInfo *cfInfo = &ss.cfData[0].cfInfo[i];
7867
7868                 cfInfo->status = (CallForwardInfoStatus) cf.status;
7869                 cfInfo->reason = cf.reason;
7870                 cfInfo->serviceClass = cf.serviceClass;
7871                 cfInfo->toa = cf.toa;
7872                 cfInfo->number = convertCharPtrToHidlString(cf.number);
7873                 cfInfo->timeSeconds = cf.timeSeconds;
7874#if VDBG
7875                 RLOGD("onSupplementaryServiceIndicationInd: "
7876                        "Data: %d,reason=%d,cls=%d,toa=%d,num=%s,tout=%d],", cf.status,
7877                        cf.reason, cf.serviceClass, cf.toa, (char*)cf.number, cf.timeSeconds);
7878#endif
7879            }
7880        } else {
7881            ss.ssInfo.resize(1);
7882            ss.cfData.resize(0);
7883
7884            /* each int */
7885            ss.ssInfo[0].ssInfo.resize(SS_INFO_MAX);
7886            for (int i = 0; i < SS_INFO_MAX; i++) {
7887#if VDBG
7888                 RLOGD("onSupplementaryServiceIndicationInd: Data: %d",
7889                        rilSsResponse->ssInfo[i]);
7890#endif
7891                 ss.ssInfo[0].ssInfo[i] = rilSsResponse->ssInfo[i];
7892            }
7893        }
7894
7895#if VDBG
7896        RLOGD("onSupplementaryServiceIndicationInd");
7897#endif
7898        Return<void> retStatus = radioService[slotId]->mRadioIndication->
7899                onSupplementaryServiceIndication(convertIntToRadioIndicationType(indicationType),
7900                ss);
7901        radioService[slotId]->checkReturnStatus(retStatus);
7902    } else {
7903        RLOGE("onSupplementaryServiceIndicationInd: "
7904                "radioService[%d]->mRadioIndication == NULL", slotId);
7905    }
7906
7907    return 0;
7908}
7909
7910int radio::stkCallControlAlphaNotifyInd(int slotId,
7911                                        int indicationType, int token, RIL_Errno e, void *response,
7912                                        size_t responseLen) {
7913    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7914        if (response == NULL || responseLen == 0) {
7915            RLOGE("stkCallControlAlphaNotifyInd: invalid response");
7916            return 0;
7917        }
7918#if VDBG
7919        RLOGD("stkCallControlAlphaNotifyInd");
7920#endif
7921        Return<void> retStatus = radioService[slotId]->mRadioIndication->stkCallControlAlphaNotify(
7922                convertIntToRadioIndicationType(indicationType),
7923                convertCharPtrToHidlString((char *) response));
7924        radioService[slotId]->checkReturnStatus(retStatus);
7925    } else {
7926        RLOGE("stkCallControlAlphaNotifyInd: radioService[%d]->mRadioIndication == NULL",
7927                slotId);
7928    }
7929
7930    return 0;
7931}
7932
7933void convertRilLceDataInfoToHal(void *response, size_t responseLen, LceDataInfo& lce) {
7934    RIL_LceDataInfo *rilLceDataInfo = (RIL_LceDataInfo *)response;
7935    lce.lastHopCapacityKbps = rilLceDataInfo->last_hop_capacity_kbps;
7936    lce.confidenceLevel = rilLceDataInfo->confidence_level;
7937    lce.lceSuspended = rilLceDataInfo->lce_suspended;
7938}
7939
7940int radio::lceDataInd(int slotId,
7941                      int indicationType, int token, RIL_Errno e, void *response,
7942                      size_t responseLen) {
7943    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7944        if (response == NULL || responseLen != sizeof(RIL_LceDataInfo)) {
7945            RLOGE("lceDataInd: invalid response");
7946            return 0;
7947        }
7948
7949        LceDataInfo lce = {};
7950        convertRilLceDataInfoToHal(response, responseLen, lce);
7951#if VDBG
7952        RLOGD("lceDataInd");
7953#endif
7954        Return<void> retStatus = radioService[slotId]->mRadioIndication->lceData(
7955                convertIntToRadioIndicationType(indicationType), lce);
7956        radioService[slotId]->checkReturnStatus(retStatus);
7957    } else {
7958        RLOGE("lceDataInd: radioService[%d]->mRadioIndication == NULL", slotId);
7959    }
7960
7961    return 0;
7962}
7963
7964int radio::pcoDataInd(int slotId,
7965                      int indicationType, int token, RIL_Errno e, void *response,
7966                      size_t responseLen) {
7967    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7968        if (response == NULL || responseLen != sizeof(RIL_PCO_Data)) {
7969            RLOGE("pcoDataInd: invalid response");
7970            return 0;
7971        }
7972
7973        PcoDataInfo pco = {};
7974        RIL_PCO_Data *rilPcoData = (RIL_PCO_Data *)response;
7975        pco.cid = rilPcoData->cid;
7976        pco.bearerProto = convertCharPtrToHidlString(rilPcoData->bearer_proto);
7977        pco.pcoId = rilPcoData->pco_id;
7978        pco.contents.setToExternal((uint8_t *) rilPcoData->contents, rilPcoData->contents_length);
7979
7980#if VDBG
7981        RLOGD("pcoDataInd");
7982#endif
7983        Return<void> retStatus = radioService[slotId]->mRadioIndication->pcoData(
7984                convertIntToRadioIndicationType(indicationType), pco);
7985        radioService[slotId]->checkReturnStatus(retStatus);
7986    } else {
7987        RLOGE("pcoDataInd: radioService[%d]->mRadioIndication == NULL", slotId);
7988    }
7989
7990    return 0;
7991}
7992
7993int radio::modemResetInd(int slotId,
7994                         int indicationType, int token, RIL_Errno e, void *response,
7995                         size_t responseLen) {
7996    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
7997        if (response == NULL || responseLen == 0) {
7998            RLOGE("modemResetInd: invalid response");
7999            return 0;
8000        }
8001#if VDBG
8002        RLOGD("modemResetInd");
8003#endif
8004        Return<void> retStatus = radioService[slotId]->mRadioIndication->modemReset(
8005                convertIntToRadioIndicationType(indicationType),
8006                convertCharPtrToHidlString((char *) response));
8007        radioService[slotId]->checkReturnStatus(retStatus);
8008    } else {
8009        RLOGE("modemResetInd: radioService[%d]->mRadioIndication == NULL", slotId);
8010    }
8011
8012    return 0;
8013}
8014
8015int radio::oemHookRawInd(int slotId,
8016                         int indicationType, int token, RIL_Errno e, void *response,
8017                         size_t responseLen) {
8018    if (oemHookService[slotId] != NULL && oemHookService[slotId]->mOemHookIndication != NULL) {
8019        if (response == NULL || responseLen == 0) {
8020            RLOGE("oemHookRawInd: invalid response");
8021            return 0;
8022        }
8023
8024        hidl_vec<uint8_t> data;
8025        data.setToExternal((uint8_t *) response, responseLen);
8026#if VDBG
8027        RLOGD("oemHookRawInd");
8028#endif
8029        Return<void> retStatus = oemHookService[slotId]->mOemHookIndication->oemHookRaw(
8030                convertIntToRadioIndicationType(indicationType), data);
8031        checkReturnStatus(slotId, retStatus, false);
8032    } else {
8033        RLOGE("oemHookRawInd: oemHookService[%d]->mOemHookIndication == NULL", slotId);
8034    }
8035
8036    return 0;
8037}
8038
8039void radio::registerService(RIL_RadioFunctions *callbacks, CommandInfo *commands) {
8040    using namespace android::hardware;
8041    int simCount = 1;
8042    const char *serviceNames[] = {
8043            android::RIL_getServiceName()
8044            #if (SIM_COUNT >= 2)
8045            , RIL2_SERVICE_NAME
8046            #if (SIM_COUNT >= 3)
8047            , RIL3_SERVICE_NAME
8048            #if (SIM_COUNT >= 4)
8049            , RIL4_SERVICE_NAME
8050            #endif
8051            #endif
8052            #endif
8053            };
8054
8055    #if (SIM_COUNT >= 2)
8056    simCount = SIM_COUNT;
8057    #endif
8058
8059    configureRpcThreadpool(1, true /* callerWillJoin */);
8060    for (int i = 0; i < simCount; i++) {
8061        pthread_rwlock_t *radioServiceRwlockPtr = getRadioServiceRwlock(i);
8062        int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr);
8063        assert(ret == 0);
8064
8065        radioService[i] = new RadioImpl;
8066        radioService[i]->mSlotId = i;
8067        oemHookService[i] = new OemHookImpl;
8068        oemHookService[i]->mSlotId = i;
8069        RLOGD("registerService: starting IRadio %s", serviceNames[i]);
8070        android::status_t status = radioService[i]->registerAsService(serviceNames[i]);
8071        status = oemHookService[i]->registerAsService(serviceNames[i]);
8072
8073        ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
8074        assert(ret == 0);
8075    }
8076
8077    s_vendorFunctions = callbacks;
8078    s_commands = commands;
8079}
8080
8081void rilc_thread_pool() {
8082    joinRpcThreadpool();
8083}
8084
8085pthread_rwlock_t * radio::getRadioServiceRwlock(int slotId) {
8086    pthread_rwlock_t *radioServiceRwlockPtr = &radioServiceRwlock;
8087
8088    #if (SIM_COUNT >= 2)
8089    if (slotId == 2) radioServiceRwlockPtr = &radioServiceRwlock2;
8090    #if (SIM_COUNT >= 3)
8091    if (slotId == 3) radioServiceRwlockPtr = &radioServiceRwlock3;
8092    #if (SIM_COUNT >= 4)
8093    if (slotId == 4) radioServiceRwlockPtr = &radioServiceRwlock4;
8094    #endif
8095    #endif
8096    #endif
8097
8098    return radioServiceRwlockPtr;
8099}
8100