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