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