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