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