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