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