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