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