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