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