1 /*
2 **
3 ** Copyright 2020, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #define LOG_TAG "RILC"
19 
20 #include "RefRadioConfig.h"
21 
22 #include <android-base/logging.h>
23 #include <android/binder_manager.h>
24 #include <android/binder_process.h>
25 #include <android/hardware/radio/config/1.1/IRadioConfig.h>
26 #include <android/hardware/radio/config/1.2/IRadioConfigIndication.h>
27 #include <android/hardware/radio/config/1.2/IRadioConfigResponse.h>
28 #include <android/hardware/radio/config/1.3/IRadioConfig.h>
29 #include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
30 #include <libradiocompat/RadioConfig.h>
31 
32 #include <ril.h>
33 #include <guest/hals/ril/reference-libril/ril_service.h>
34 #include <hidl/HidlTransportSupport.h>
35 
36 using namespace android::hardware::radio::V1_0;
37 using namespace android::hardware::radio::config;
38 using namespace android::hardware::radio::config::V1_0;
39 using namespace android::hardware::radio::config::V1_3;
40 using ::android::hardware::Return;
41 using ::android::hardware::hidl_string;
42 using ::android::hardware::hidl_vec;
43 using ::android::hardware::Void;
44 using android::CommandInfo;
45 using android::RequestInfo;
46 using android::requestToString;
47 using android::sp;
48 
49 RIL_RadioFunctions *s_vendorFunctions_config = NULL;
50 static CommandInfo *s_configCommands;
51 struct RadioConfigImpl;
52 sp<RadioConfigImpl> radioConfigService;
53 volatile int32_t mCounterRadioConfig;
54 
55 #if defined (ANDROID_MULTI_SIM)
56 #define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c), (d))
57 #define CALL_ONREQUEST(a, b, c, d, e) s_vendorFunctions_config->onRequest((a), (b), (c), (d), (e))
58 #define CALL_ONSTATEREQUEST(a) s_vendorFunctions_config->onStateRequest(a)
59 #else
60 #define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c))
61 #define CALL_ONREQUEST(a, b, c, d, e) s_vendorFunctions_config->onRequest((a), (b), (c), (d))
62 #define CALL_ONSTATEREQUEST(a) s_vendorFunctions_config->onStateRequest()
63 #endif
64 
65 extern void populateResponseInfo(RadioResponseInfo& responseInfo, int serial, int responseType,
66                 RIL_Errno e);
67 
68 extern void populateResponseInfo_1_6(
69     ::android::hardware::radio::V1_6::RadioResponseInfo &responseInfo,
70     int serial, int responseType, RIL_Errno e);
71 
72 extern bool dispatchVoid(int serial, int slotId, int request);
73 extern bool dispatchString(int serial, int slotId, int request, const char * str);
74 extern bool dispatchStrings(int serial, int slotId, int request, bool allowEmpty,
75                 int countStrings, ...);
76 extern bool dispatchInts(int serial, int slotId, int request, int countInts, ...);
77 extern hidl_string convertCharPtrToHidlString(const char *ptr);
78 extern void sendErrorResponse(android::RequestInfo *pRI, RIL_Errno err);
79 extern RadioIndicationType convertIntToRadioIndicationType(int indicationType);
80 
81 extern bool isChangeSlotId(int serviceId, int slotId);
82 
83 struct RadioConfigImpl : public V1_3::IRadioConfig {
84     int32_t mSlotId;
85     sp<V1_0::IRadioConfigResponse> mRadioConfigResponse;
86     sp<V1_0::IRadioConfigIndication> mRadioConfigIndication;
87     sp<V1_1::IRadioConfigResponse> mRadioConfigResponseV1_1;
88     sp<V1_2::IRadioConfigResponse> mRadioConfigResponseV1_2;
89     sp<V1_2::IRadioConfigIndication> mRadioConfigIndicationV1_2;
90     sp<V1_3::IRadioConfigResponse> mRadioConfigResponseV1_3;
91 
92     Return<void> setResponseFunctions(
93             const ::android::sp<V1_0::IRadioConfigResponse>& radioConfigResponse,
94             const ::android::sp<V1_0::IRadioConfigIndication>& radioConfigIndication);
95 
96     Return<void> getSimSlotsStatus(int32_t serial);
97 
98     Return<void> setSimSlotsMapping(int32_t serial, const hidl_vec<uint32_t>& slotMap);
99 
100     Return<void> getPhoneCapability(int32_t serial);
101 
102     Return<void> setPreferredDataModem(int32_t serial, uint8_t modemId);
103 
104     Return<void> setModemsConfig(int32_t serial, const V1_1::ModemsConfig& modemsConfig);
105 
106     Return<void> getModemsConfig(int32_t serial);
107 
108     Return<void> getHalDeviceCapabilities(int32_t serial);
109 
110     void checkReturnStatus_config(Return<void>& ret);
111 };
setResponseFunctions(const::android::sp<V1_0::IRadioConfigResponse> & radioConfigResponse,const::android::sp<V1_0::IRadioConfigIndication> & radioConfigIndication)112 Return<void> RadioConfigImpl::setResponseFunctions(
113         const ::android::sp<V1_0::IRadioConfigResponse>& radioConfigResponse,
114         const ::android::sp<V1_0::IRadioConfigIndication>& radioConfigIndication) {
115     pthread_rwlock_t *radioServiceRwlockPtr = radio_1_6::getRadioServiceRwlock(RIL_SOCKET_1);
116     int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr);
117     CHECK_EQ(ret, 0);
118 
119     mRadioConfigResponse = radioConfigResponse;
120     mRadioConfigIndication = radioConfigIndication;
121 
122 
123     mRadioConfigResponseV1_1 =
124         V1_1::IRadioConfigResponse::castFrom(mRadioConfigResponse).withDefault(nullptr);
125     if (mRadioConfigResponseV1_1 == nullptr) {
126         mRadioConfigResponseV1_1 = nullptr;
127     }
128 
129     mRadioConfigResponseV1_2 =
130         V1_2::IRadioConfigResponse::castFrom(mRadioConfigResponse).withDefault(nullptr);
131     mRadioConfigIndicationV1_2 =
132         V1_2::IRadioConfigIndication::castFrom(mRadioConfigIndication).withDefault(nullptr);
133     if (mRadioConfigResponseV1_2 == nullptr || mRadioConfigIndicationV1_2 == nullptr) {
134         mRadioConfigResponseV1_2 = nullptr;
135         mRadioConfigIndicationV1_2 = nullptr;
136     }
137 
138     mRadioConfigResponseV1_3 =
139         V1_3::IRadioConfigResponse::castFrom(mRadioConfigResponse).withDefault(nullptr);
140     if (mRadioConfigResponseV1_3 == nullptr || mRadioConfigResponseV1_3 == nullptr) {
141         mRadioConfigResponseV1_3 = nullptr;
142     }
143 
144     mCounterRadioConfig++;
145 
146     ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
147     CHECK_EQ(ret, 0);
148 
149     return Void();
150 }
151 
getSimSlotsStatus(int32_t serial)152 Return<void> RadioConfigImpl::getSimSlotsStatus(int32_t serial) {
153 #if VDBG
154     RLOGD("getSimSlotsStatus: serial %d", serial);
155 #endif
156     dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFIG_GET_SLOT_STATUS);
157 
158     return Void();
159 }
160 
setSimSlotsMapping(int32_t serial,const hidl_vec<uint32_t> & slotMap)161 Return<void> RadioConfigImpl::setSimSlotsMapping(int32_t serial, const hidl_vec<uint32_t>& slotMap) {
162 #if VDBG
163     RLOGD("setSimSlotsMapping: serial %d", serial);
164 #endif
165     RequestInfo *pRI = android::addRequestToList(serial, RIL_SOCKET_1,
166         RIL_REQUEST_CONFIG_SET_SLOT_MAPPING);
167     if (pRI == NULL) {
168         return Void();
169     }
170     size_t slotNum = slotMap.size();
171 
172     if (slotNum > MAX_LOGICAL_MODEM_NUM) {
173         RLOGE("setSimSlotsMapping: invalid parameter");
174         sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
175         return Void();
176     }
177 
178     for (size_t socket_id = 0; socket_id < slotNum; socket_id++) {
179         if (slotMap[socket_id] >= MAX_LOGICAL_MODEM_NUM) {
180             RLOGE("setSimSlotsMapping: invalid parameter[%zu]", socket_id);
181             sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
182             return Void();
183         }
184         // confirm logical id is not duplicate
185         for (size_t nextId = socket_id + 1; nextId < slotNum; nextId++) {
186             if (slotMap[socket_id] == slotMap[nextId]) {
187                 RLOGE("setSimSlotsMapping: slot parameter is the same:[%zu] and [%zu]",
188                     socket_id, nextId);
189                 sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
190                 return Void();
191             }
192         }
193     }
194     int *pSlotMap = (int *)calloc(slotNum, sizeof(int));
195 
196     for (size_t socket_id = 0; socket_id < slotNum; socket_id++) {
197         pSlotMap[socket_id] = slotMap[socket_id];
198     }
199 
200     CALL_ONREQUEST(RIL_REQUEST_CONFIG_SET_SLOT_MAPPING, pSlotMap,
201         slotNum * sizeof(int), pRI, pRI->socket_id);
202     if (pSlotMap != NULL) {
203         free(pSlotMap);
204     }
205 
206     return Void();
207 }
208 
getPhoneCapability(int32_t serial)209 Return<void> RadioConfigImpl::getPhoneCapability(int32_t serial) {
210 #if VDBG
211     RLOGD("getPhoneCapability: serial %d", serial);
212 #endif
213     dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFIG_GET_PHONE_CAPABILITY);
214     return Void();
215 }
216 
setPreferredDataModem(int32_t serial,uint8_t modemId)217 Return<void> RadioConfigImpl::setPreferredDataModem(int32_t serial, uint8_t modemId) {
218 #if VDBG
219     RLOGD("setPreferredDataModem: serial %d", serial);
220 #endif
221     dispatchInts(serial, mSlotId, RIL_REQUEST_CONFIG_SET_PREFER_DATA_MODEM, 1, modemId);
222     return Void();
223 }
224 
setModemsConfig(int32_t serial,const V1_1::ModemsConfig & modemsConfig)225 Return<void> RadioConfigImpl::setModemsConfig(int32_t serial, const V1_1::ModemsConfig& modemsConfig) {
226 #if VDBG
227     RLOGD("setModemsConfig: serial %d", serial);
228 #endif
229     RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
230         RIL_REQUEST_CONFIG_SET_MODEM_CONFIG);
231     if (pRI == NULL) {
232         return Void();
233     }
234 
235     RIL_ModemConfig mdConfig = {};
236 
237     mdConfig.numOfLiveModems = modemsConfig.numOfLiveModems;
238 
239 
240     CALL_ONREQUEST(RIL_REQUEST_CONFIG_SET_MODEM_CONFIG, &mdConfig,
241         sizeof(RIL_ModemConfig), pRI, pRI->socket_id);
242 
243     return Void();
244 }
245 
getModemsConfig(int32_t serial)246 Return<void> RadioConfigImpl::getModemsConfig(int32_t serial) {
247 #if VDBG
248     RLOGD("getModemsConfig: serial %d", serial);
249 #endif
250     dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFIG_GET_MODEM_CONFIG);
251     return Void();
252 }
253 
getHalDeviceCapabilities(int32_t serial)254 Return<void> RadioConfigImpl::getHalDeviceCapabilities(int32_t serial) {
255 #if VDBG
256     RLOGD("getHalDeviceCapabilities: serial %d", serial);
257 #endif
258     dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFIG_GET_HAL_DEVICE_CAPABILITIES);
259     return Void();
260 }
261 
registerConfigService(RIL_RadioFunctions * callbacks,CommandInfo * commands)262 void radio_1_6::registerConfigService(RIL_RadioFunctions *callbacks, CommandInfo *commands) {
263     using namespace android::hardware;
264     using namespace std::string_literals;
265     namespace compat = android::hardware::radio::compat;
266 
267     RLOGD("Entry %s", __FUNCTION__);
268     const char *serviceNames = "default";
269 
270     s_vendorFunctions_config = callbacks;
271     s_configCommands = commands;
272 
273     int slotId = RIL_SOCKET_1;
274 
275     pthread_rwlock_t *radioServiceRwlockPtr = getRadioServiceRwlock(0);
276     int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr);
277     CHECK_EQ(ret, 0);
278     RLOGD("registerConfigService: starting V1_2::IConfigRadio %s", serviceNames);
279     radioConfigService = new RadioConfigImpl;
280 
281     radioConfigService->mSlotId = slotId;
282     radioConfigService->mRadioConfigResponse = NULL;
283     radioConfigService->mRadioConfigIndication = NULL;
284     radioConfigService->mRadioConfigResponseV1_1 = NULL;
285     radioConfigService->mRadioConfigResponseV1_2 = NULL;
286     radioConfigService->mRadioConfigResponseV1_3 = NULL;
287     radioConfigService->mRadioConfigIndicationV1_2 = NULL;
288 
289     // use a compat shim to convert HIDL interface to AIDL and publish it
290     // TODO(bug 220004469): replace with a full AIDL implementation
291     static auto aidlHal = ndk::SharedRefBase::make<cf::ril::RefRadioConfig>(radioConfigService);
292     const auto instance = compat::RadioConfig::descriptor + "/"s + std::string(serviceNames);
293     const auto status = AServiceManager_addService(aidlHal->asBinder().get(), instance.c_str());
294     RLOGD("registerConfigService addService: status %d", status);
295     CHECK_EQ(status, STATUS_OK);
296 
297     ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
298     CHECK_EQ(ret, 0);
299 }
300 
checkReturnStatus(Return<void> & ret)301 void checkReturnStatus(Return<void>& ret) {
302     if (ret.isOk() == false) {
303         RLOGE("checkReturnStatus_config: unable to call response/indication callback");
304         // Remote process hosting the callbacks must be dead. Reset the callback objects;
305         // there's no other recovery to be done here. When the client process is back up, it will
306         // call setResponseFunctions()
307 
308         // Caller should already hold rdlock, release that first
309         // note the current counter to avoid overwriting updates made by another thread before
310         // write lock is acquired.
311         int counter = mCounterRadioConfig;
312         pthread_rwlock_t *radioServiceRwlockPtr = radio_1_6::getRadioServiceRwlock(0);
313         int ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
314         CHECK_EQ(ret, 0);
315 
316         // acquire wrlock
317         ret = pthread_rwlock_wrlock(radioServiceRwlockPtr);
318         CHECK_EQ(ret, 0);
319 
320         // make sure the counter value has not changed
321         if (counter == mCounterRadioConfig) {
322             radioConfigService->mRadioConfigResponse = NULL;
323             radioConfigService->mRadioConfigIndication = NULL;
324             radioConfigService->mRadioConfigResponseV1_1 = NULL;
325             radioConfigService->mRadioConfigResponseV1_2 = NULL;
326             radioConfigService->mRadioConfigResponseV1_3 = NULL;
327             radioConfigService->mRadioConfigIndicationV1_2 = NULL;
328             mCounterRadioConfig++;
329         } else {
330             RLOGE("checkReturnStatus_config: not resetting responseFunctions as they likely "
331                   "got updated on another thread");
332         }
333 
334         // release wrlock
335         ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
336         CHECK_EQ(ret, 0);
337 
338         // Reacquire rdlock
339         ret = pthread_rwlock_rdlock(radioServiceRwlockPtr);
340         CHECK_EQ(ret, 0);
341     }
342 }
343 
checkReturnStatus_config(Return<void> & ret)344 void RadioConfigImpl::checkReturnStatus_config(Return<void>& ret) {
345     ::checkReturnStatus(ret);
346 }
347 
getSimSlotsStatusResponse(int slotId,int responseType,int serial,RIL_Errno e,void * response,size_t responseLen)348 int radio_1_6::getSimSlotsStatusResponse(int slotId, int responseType, int serial,
349                                      RIL_Errno e, void *response, size_t responseLen) {
350 #if VDBG
351     RLOGD("getSimSlotsResponse: serial %d", serial);
352 #endif
353 
354     if (radioConfigService->mRadioConfigResponse != NULL) {
355         RadioResponseInfo responseInfo = {};
356         populateResponseInfo(responseInfo, serial, responseType, e);
357         hidl_vec<SimSlotStatus> simSlotStatus = {};
358 
359         if ((response == NULL) || (responseLen % sizeof(RIL_SimSlotStatus_V1_2) != 0)) {
360             RLOGE("getSimSlotsStatusResponse: Invalid response");
361             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
362         } else {
363             RIL_SimSlotStatus_V1_2 *psimSlotStatus = ((RIL_SimSlotStatus_V1_2 *) response);
364             int num = responseLen / sizeof(RIL_SimSlotStatus_V1_2);
365             simSlotStatus.resize(num);
366             for (int i = 0; i < num; i++) {
367                 simSlotStatus[i].cardState = (CardState)psimSlotStatus->base.cardState;
368                 simSlotStatus[i].slotState = (SlotState)psimSlotStatus->base.slotState;
369                 simSlotStatus[i].atr = convertCharPtrToHidlString(psimSlotStatus->base.atr);
370                 simSlotStatus[i].logicalSlotId = psimSlotStatus->base.logicalSlotId;
371                 simSlotStatus[i].iccid = convertCharPtrToHidlString(psimSlotStatus->base.iccid);
372                 psimSlotStatus += 1;
373             }
374         }
375         Return<void> retStatus = radioConfigService->mRadioConfigResponse->getSimSlotsStatusResponse(
376                 responseInfo, simSlotStatus);
377         radioConfigService->checkReturnStatus_config(retStatus);
378     } else {
379         RLOGE("getSimSlotsResponse: radioConfigService->mRadioConfigResponse == NULL");
380     }
381 
382     return 0;
383 }
384 
setSimSlotsMappingResponse(int slotId,int responseType,int serial,RIL_Errno e,void * response,size_t responseLen)385 int radio_1_6::setSimSlotsMappingResponse(int slotId, int responseType, int serial,
386                                       RIL_Errno e, void *response, size_t responseLen) {
387 #if VDBG
388     RLOGD("setSimSlotsMappingResponse: serial %d", serial);
389 #endif
390 
391     if (radioConfigService->mRadioConfigResponse != NULL) {
392         RadioResponseInfo responseInfo = {};
393         populateResponseInfo(responseInfo, serial, responseType, e);
394         Return<void> retStatus = radioConfigService->mRadioConfigResponse->setSimSlotsMappingResponse(
395                 responseInfo);
396         radioConfigService->checkReturnStatus_config(retStatus);
397     } else {
398         RLOGE("setSimSlotsMappingResponse: radioConfigService->mRadioConfigResponse == NULL");
399     }
400 
401     return 0;
402 }
403 
getPhoneCapabilityResponse(int slotId,int responseType,int serial,RIL_Errno e,void * response,size_t responseLen)404 int radio_1_6::getPhoneCapabilityResponse(int slotId, int responseType, int serial,
405                                       RIL_Errno e, void *response, size_t responseLen) {
406 #if VDBG
407     RLOGD("getPhoneCapabilityResponse: serial %d", serial);
408 #endif
409 
410     if (radioConfigService->mRadioConfigResponseV1_1 != NULL) {
411         RadioResponseInfo responseInfo = {};
412         populateResponseInfo(responseInfo, serial, responseType, e);
413         V1_1::PhoneCapability phoneCapability = {};
414         if ((response == NULL) || (responseLen % sizeof(RIL_PhoneCapability) != 0)) {
415             RLOGE("getPhoneCapabilityResponse Invalid response: NULL");
416             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
417         } else {
418             RIL_PhoneCapability *pCapability = (RIL_PhoneCapability *)response;
419             phoneCapability.maxActiveData = pCapability->maxActiveData;
420             phoneCapability.maxActiveInternetData = pCapability->maxActiveInternetData;
421             phoneCapability.isInternetLingeringSupported = pCapability->isInternetLingeringSupported;
422             phoneCapability.logicalModemList.resize(SIM_COUNT);
423             for (int i = 0 ; i < SIM_COUNT; i++) {
424                 RIL_ModemInfo logicalModemInfo = pCapability->logicalModemList[i];
425                 phoneCapability.logicalModemList[i].modemId = logicalModemInfo.modemId;
426             }
427         }
428         Return<void> retStatus = radioConfigService->mRadioConfigResponseV1_1->getPhoneCapabilityResponse(
429                 responseInfo, phoneCapability);
430         radioConfigService->checkReturnStatus_config(retStatus);
431     } else {
432         RLOGE("getPhoneCapabilityResponse: radioConfigService->mRadioConfigResponseV1_1 == NULL");
433     }
434 
435     return 0;
436 }
437 
setPreferredDataModemResponse(int slotId,int responseType,int serial,RIL_Errno e,void * response,size_t responseLen)438 int radio_1_6::setPreferredDataModemResponse(int slotId, int responseType, int serial,
439                                          RIL_Errno e, void *response, size_t responseLen) {
440 #if VDBG
441     RLOGD("setPreferredDataModemResponse: serial %d", serial);
442 #endif
443 
444     if (radioConfigService->mRadioConfigResponseV1_1 != NULL) {
445         RadioResponseInfo responseInfo = {};
446         populateResponseInfo(responseInfo, serial, responseType, e);
447         Return<void> retStatus = radioConfigService->mRadioConfigResponseV1_1->setPreferredDataModemResponse(
448                 responseInfo);
449         radioConfigService->checkReturnStatus_config(retStatus);
450     } else {
451         RLOGE("setPreferredDataModemResponse: radioConfigService->mRadioConfigResponseV1_1 == NULL");
452     }
453 
454     return 0;
455 }
456 
setModemsConfigResponse(int slotId,int responseType,int serial,RIL_Errno e,void * response,size_t responseLen)457 int radio_1_6::setModemsConfigResponse(int slotId, int responseType, int serial,
458                                    RIL_Errno e, void *response, size_t responseLen) {
459 #if VDBG
460     RLOGD("setModemsConfigResponse: serial %d", serial);
461 #endif
462 
463     if (radioConfigService->mRadioConfigResponseV1_1 != NULL) {
464         RadioResponseInfo responseInfo = {};
465         populateResponseInfo(responseInfo, serial, responseType, e);
466         Return<void> retStatus = radioConfigService->mRadioConfigResponseV1_1->setModemsConfigResponse(
467                 responseInfo);
468         radioConfigService->checkReturnStatus_config(retStatus);
469     } else {
470         RLOGE("setModemsConfigResponse: radioConfigService->mRadioConfigResponseV1_1 == NULL");
471     }
472 
473     return 0;
474 }
475 
getModemsConfigResponse(int slotId,int responseType,int serial,RIL_Errno e,void * response,size_t responseLen)476 int radio_1_6::getModemsConfigResponse(int slotId, int responseType, int serial,
477                                    RIL_Errno e, void *response, size_t responseLen) {
478 #if VDBG
479     RLOGD("getModemsConfigResponse: serial %d", serial);
480 #endif
481 
482     if (radioConfigService->mRadioConfigResponseV1_1 != NULL) {
483         RadioResponseInfo responseInfo = {};
484         populateResponseInfo(responseInfo, serial, responseType, e);
485         V1_1::ModemsConfig mdCfg = {};
486         RIL_ModemConfig *pMdCfg = (RIL_ModemConfig *)response;
487         if ((response == NULL) || (responseLen != sizeof(RIL_ModemConfig))) {
488             RLOGE("getModemsConfigResponse Invalid response: NULL");
489             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
490         } else {
491             mdCfg.numOfLiveModems = pMdCfg->numOfLiveModems;
492         }
493         Return<void> retStatus = radioConfigService->mRadioConfigResponseV1_1->getModemsConfigResponse(
494                 responseInfo, mdCfg);
495         radioConfigService->checkReturnStatus_config(retStatus);
496     } else {
497         RLOGE("getModemsConfigResponse: radioConfigService->mRadioConfigResponseV1_1 == NULL");
498     }
499 
500     return 0;
501 }
502 
getHalDeviceCapabilitiesResponse(int slotId,int responseType,int serial,RIL_Errno e,void * response,size_t responseLen)503 int radio_1_6::getHalDeviceCapabilitiesResponse(int slotId, int responseType, int serial,
504                                    RIL_Errno e, void *response, size_t responseLen) {
505 #if VDBG
506     RLOGD("getHalDeviceCapabilitiesResponse: serial %d", serial);
507 #endif
508 
509     if (radioConfigService->mRadioConfigResponseV1_3 != NULL) {
510         ::android::hardware::radio::V1_6::RadioResponseInfo responseInfo = {};
511         populateResponseInfo_1_6(responseInfo, serial, responseType, e);
512 
513         bool modemReducedFeatureSet1 = false;
514         if (response == NULL || responseLen != sizeof(bool)) {
515             RLOGE("getHalDeviceCapabilitiesResponse Invalid response.");
516         } else {
517             modemReducedFeatureSet1 = (*((bool *) response));
518         }
519 
520         Return<void> retStatus = radioConfigService->mRadioConfigResponseV1_3->getHalDeviceCapabilitiesResponse(
521                 responseInfo, modemReducedFeatureSet1);
522         radioConfigService->checkReturnStatus_config(retStatus);
523     } else {
524         RLOGE("getHalDeviceCapabilitiesResponse: radioConfigService->getHalDeviceCapabilities == NULL");
525     }
526 
527     return 0;
528 }
529 
simSlotsStatusChanged(int slotId,int indicationType,int token,RIL_Errno e,void * response,size_t responseLen)530 int radio_1_6::simSlotsStatusChanged(int slotId, int indicationType, int token, RIL_Errno e,
531                                  void *response, size_t responseLen) {
532     if (radioConfigService != NULL &&
533         (radioConfigService->mRadioConfigIndication != NULL ||
534          radioConfigService->mRadioConfigIndicationV1_2 != NULL)) {
535         if ((response == NULL) || (responseLen % sizeof(RIL_SimSlotStatus_V1_2) != 0)) {
536             RLOGE("simSlotsStatusChanged: invalid response");
537             return 0;
538         }
539 
540         RIL_SimSlotStatus_V1_2 *psimSlotStatus = ((RIL_SimSlotStatus_V1_2 *)response);
541         int num = responseLen / sizeof(RIL_SimSlotStatus_V1_2);
542         if (radioConfigService->mRadioConfigIndication != NULL) {
543             hidl_vec<SimSlotStatus> simSlotStatus = {};
544             simSlotStatus.resize(num);
545             for (int i = 0; i < num; i++) {
546                 simSlotStatus[i].cardState = (CardState) psimSlotStatus->base.cardState;
547                 simSlotStatus[i].slotState = (SlotState) psimSlotStatus->base.slotState;
548                 simSlotStatus[i].atr = convertCharPtrToHidlString(psimSlotStatus->base.atr);
549                 simSlotStatus[i].logicalSlotId = psimSlotStatus->base.logicalSlotId;
550                 simSlotStatus[i].iccid = convertCharPtrToHidlString(psimSlotStatus->base.iccid);
551 #if VDBG
552                 RLOGD("simSlotsStatusChanged: cardState %d slotState %d", simSlotStatus[i].cardState,
553                         simSlotStatus[i].slotState);
554 #endif
555                 psimSlotStatus += 1;
556             }
557 
558             Return<void> retStatus = radioConfigService->mRadioConfigIndication->simSlotsStatusChanged(
559                     convertIntToRadioIndicationType(indicationType), simSlotStatus);
560             radioConfigService->checkReturnStatus_config(retStatus);
561         } else if (radioConfigService->mRadioConfigIndicationV1_2) {
562             hidl_vec<V1_2::SimSlotStatus> simSlotStatus;
563             simSlotStatus.resize(num);
564             for (int i = 0; i < num; i++) {
565                 simSlotStatus[i].base.cardState = (CardState)(psimSlotStatus->base.cardState);
566                 simSlotStatus[i].base.slotState = (SlotState) psimSlotStatus->base.slotState;
567                 simSlotStatus[i].base.atr = convertCharPtrToHidlString(psimSlotStatus->base.atr);
568                 simSlotStatus[i].base.logicalSlotId = psimSlotStatus->base.logicalSlotId;
569                 simSlotStatus[i].base.iccid = convertCharPtrToHidlString(psimSlotStatus->base.iccid);
570                 simSlotStatus[i].eid = convertCharPtrToHidlString(psimSlotStatus->eid);
571                 psimSlotStatus += 1;
572 #if VDBG
573             RLOGD("simSlotsStatusChanged_1_2: cardState %d slotState %d",
574                     simSlotStatus[i].base.cardState, simSlotStatus[i].base.slotState);
575 #endif
576             }
577 
578             Return<void> retStatus = radioConfigService->mRadioConfigIndicationV1_2->simSlotsStatusChanged_1_2(
579                     convertIntToRadioIndicationType(indicationType), simSlotStatus);
580             radioConfigService->checkReturnStatus_config(retStatus);
581         }
582     } else {
583         RLOGE("simSlotsStatusChanged: radioService->mRadioIndication == NULL");
584     }
585 
586     return 0;
587 }
588