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 <android/hardware/radio/config/1.1/IRadioConfig.h>
21 #include <android/hardware/radio/config/1.2/IRadioConfigResponse.h>
22 #include <android/hardware/radio/config/1.2/IRadioConfigIndication.h>
23 #include <android/hardware/radio/1.1/types.h>
24
25 #include <ril.h>
26 #include <guest/hals/ril/reference-libril/ril_service.h>
27 #include <hidl/HidlTransportSupport.h>
28
29 using namespace android::hardware::radio::V1_0;
30 using namespace android::hardware::radio::config;
31 using namespace android::hardware::radio::config::V1_0;
32 using ::android::hardware::configureRpcThreadpool;
33 using ::android::hardware::joinRpcThreadpool;
34 using ::android::hardware::Return;
35 using ::android::hardware::hidl_string;
36 using ::android::hardware::hidl_vec;
37 using ::android::hardware::Void;
38 using android::CommandInfo;
39 using android::RequestInfo;
40 using android::requestToString;
41 using android::sp;
42
43 RIL_RadioFunctions *s_vendorFunctions_config = NULL;
44 static CommandInfo *s_configCommands;
45 struct RadioConfigImpl;
46 sp<RadioConfigImpl> radioConfigService;
47 volatile int32_t mCounterRadioConfig;
48
49 #if defined (ANDROID_MULTI_SIM)
50 #define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c), (d))
51 #define CALL_ONREQUEST(a, b, c, d, e) s_vendorFunctions_config->onRequest((a), (b), (c), (d), (e))
52 #define CALL_ONSTATEREQUEST(a) s_vendorFunctions_config->onStateRequest(a)
53 #else
54 #define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c))
55 #define CALL_ONREQUEST(a, b, c, d, e) s_vendorFunctions_config->onRequest((a), (b), (c), (d))
56 #define CALL_ONSTATEREQUEST(a) s_vendorFunctions_config->onStateRequest()
57 #endif
58
59 extern void populateResponseInfo(RadioResponseInfo& responseInfo, int serial, int responseType,
60 RIL_Errno e);
61 extern bool dispatchVoid(int serial, int slotId, int request);
62 extern bool dispatchString(int serial, int slotId, int request, const char * str);
63 extern bool dispatchStrings(int serial, int slotId, int request, bool allowEmpty,
64 int countStrings, ...);
65 extern bool dispatchInts(int serial, int slotId, int request, int countInts, ...);
66 extern hidl_string convertCharPtrToHidlString(const char *ptr);
67 extern void sendErrorResponse(android::RequestInfo *pRI, RIL_Errno err);
68 extern RadioIndicationType convertIntToRadioIndicationType(int indicationType);
69
70 extern bool isChangeSlotId(int serviceId, int slotId);
71
72 struct RadioConfigImpl : public V1_1::IRadioConfig {
73 int32_t mSlotId;
74 sp<V1_0::IRadioConfigResponse> mRadioConfigResponse;
75 sp<V1_0::IRadioConfigIndication> mRadioConfigIndication;
76 sp<V1_1::IRadioConfigResponse> mRadioConfigResponseV1_1;
77 sp<V1_2::IRadioConfigResponse> mRadioConfigResponseV1_2;
78 sp<V1_2::IRadioConfigIndication> mRadioConfigIndicationV1_2;
79
80 Return<void> setResponseFunctions(
81 const ::android::sp<V1_0::IRadioConfigResponse>& radioConfigResponse,
82 const ::android::sp<V1_0::IRadioConfigIndication>& radioConfigIndication);
83
84 Return<void> getSimSlotsStatus(int32_t serial);
85
86 Return<void> setSimSlotsMapping(int32_t serial, const hidl_vec<uint32_t>& slotMap);
87
88 Return<void> getPhoneCapability(int32_t serial);
89
90 Return<void> setPreferredDataModem(int32_t serial, uint8_t modemId);
91
92 Return<void> setModemsConfig(int32_t serial, const V1_1::ModemsConfig& modemsConfig);
93
94 Return<void> getModemsConfig(int32_t serial);
95
96 void checkReturnStatus_config(Return<void>& ret);
97 };
setResponseFunctions(const::android::sp<V1_0::IRadioConfigResponse> & radioConfigResponse,const::android::sp<V1_0::IRadioConfigIndication> & radioConfigIndication)98 Return<void> RadioConfigImpl::setResponseFunctions(
99 const ::android::sp<V1_0::IRadioConfigResponse>& radioConfigResponse,
100 const ::android::sp<V1_0::IRadioConfigIndication>& radioConfigIndication) {
101 pthread_rwlock_t *radioServiceRwlockPtr = radio_1_6::getRadioServiceRwlock(RIL_SOCKET_1);
102 int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr);
103 assert(ret == 0);
104
105 mRadioConfigResponse = radioConfigResponse;
106 mRadioConfigIndication = radioConfigIndication;
107
108
109 mRadioConfigResponseV1_1 =
110 V1_1::IRadioConfigResponse::castFrom(mRadioConfigResponse).withDefault(nullptr);
111 if (mRadioConfigResponseV1_1 == nullptr) {
112 mRadioConfigResponseV1_1 = nullptr;
113 }
114
115 mRadioConfigResponseV1_2 =
116 V1_2::IRadioConfigResponse::castFrom(mRadioConfigResponse).withDefault(nullptr);
117 mRadioConfigIndicationV1_2 =
118 V1_2::IRadioConfigIndication::castFrom(mRadioConfigIndication).withDefault(nullptr);
119 if (mRadioConfigResponseV1_2 == nullptr || mRadioConfigIndicationV1_2 == nullptr) {
120 mRadioConfigResponseV1_2 = nullptr;
121 mRadioConfigIndicationV1_2 = nullptr;
122 }
123
124 mCounterRadioConfig++;
125
126 ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
127 assert(ret == 0);
128
129 return Void();
130 }
131
getSimSlotsStatus(int32_t serial)132 Return<void> RadioConfigImpl::getSimSlotsStatus(int32_t serial) {
133 #if VDBG
134 RLOGD("getSimSlotsStatus: serial %d", serial);
135 #endif
136 dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFIG_GET_SLOT_STATUS);
137
138 return Void();
139 }
140
setSimSlotsMapping(int32_t serial,const hidl_vec<uint32_t> & slotMap)141 Return<void> RadioConfigImpl::setSimSlotsMapping(int32_t serial, const hidl_vec<uint32_t>& slotMap) {
142 #if VDBG
143 RLOGD("setSimSlotsMapping: serial %d", serial);
144 #endif
145 RequestInfo *pRI = android::addRequestToList(serial, RIL_SOCKET_1,
146 RIL_REQUEST_CONFIG_SET_SLOT_MAPPING);
147 if (pRI == NULL) {
148 return Void();
149 }
150 size_t slotNum = slotMap.size();
151
152 if (slotNum > RIL_SOCKET_NUM) {
153 RLOGE("setSimSlotsMapping: invalid parameter");
154 sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
155 return Void();
156 }
157
158 for (size_t socket_id = 0; socket_id < slotNum; socket_id++) {
159 if (slotMap[socket_id] >= RIL_SOCKET_NUM) {
160 RLOGE("setSimSlotsMapping: invalid parameter[%zu]", socket_id);
161 sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
162 return Void();
163 }
164 // confirm logical id is not duplicate
165 for (size_t nextId = socket_id + 1; nextId < slotNum; nextId++) {
166 if (slotMap[socket_id] == slotMap[nextId]) {
167 RLOGE("setSimSlotsMapping: slot parameter is the same:[%zu] and [%zu]",
168 socket_id, nextId);
169 sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
170 return Void();
171 }
172 }
173 }
174 int *pSlotMap = (int *)calloc(slotNum, sizeof(int));
175
176 for (size_t socket_id = 0; socket_id < slotNum; socket_id++) {
177 pSlotMap[socket_id] = slotMap[socket_id];
178 }
179
180 CALL_ONREQUEST(RIL_REQUEST_CONFIG_SET_SLOT_MAPPING, pSlotMap,
181 slotNum * sizeof(int), pRI, pRI->socket_id);
182 if (pSlotMap != NULL) {
183 free(pSlotMap);
184 }
185
186 return Void();
187 }
188
getPhoneCapability(int32_t serial)189 Return<void> RadioConfigImpl::getPhoneCapability(int32_t serial) {
190 #if VDBG
191 RLOGD("getPhoneCapability: serial %d", serial);
192 #endif
193 dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFIG_GET_PHONE_CAPABILITY);
194 return Void();
195 }
196
setPreferredDataModem(int32_t serial,uint8_t modemId)197 Return<void> RadioConfigImpl::setPreferredDataModem(int32_t serial, uint8_t modemId) {
198 #if VDBG
199 RLOGD("setPreferredDataModem: serial %d", serial);
200 #endif
201 dispatchInts(serial, mSlotId, RIL_REQUEST_CONFIG_SET_PREFER_DATA_MODEM, 1, modemId);
202 return Void();
203 }
204
setModemsConfig(int32_t serial,const V1_1::ModemsConfig & modemsConfig)205 Return<void> RadioConfigImpl::setModemsConfig(int32_t serial, const V1_1::ModemsConfig& modemsConfig) {
206 #if VDBG
207 RLOGD("setModemsConfig: serial %d", serial);
208 #endif
209 RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
210 RIL_REQUEST_CONFIG_SET_MODEM_CONFIG);
211 if (pRI == NULL) {
212 return Void();
213 }
214
215 RIL_ModemConfig mdConfig = {};
216
217 mdConfig.numOfLiveModems = modemsConfig.numOfLiveModems;
218
219
220 CALL_ONREQUEST(RIL_REQUEST_CONFIG_SET_MODEM_CONFIG, &mdConfig,
221 sizeof(RIL_ModemConfig), pRI, pRI->socket_id);
222
223 return Void();
224 }
225
getModemsConfig(int32_t serial)226 Return<void> RadioConfigImpl::getModemsConfig(int32_t serial) {
227 #if VDBG
228 RLOGD("getModemsConfig: serial %d", serial);
229 #endif
230 dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFIG_GET_MODEM_CONFIG);
231 return Void();
232 }
233
registerConfigService(RIL_RadioFunctions * callbacks,CommandInfo * commands)234 void radio_1_6::registerConfigService(RIL_RadioFunctions *callbacks, CommandInfo *commands) {
235 using namespace android::hardware;
236 RLOGD("Entry %s", __FUNCTION__);
237 const char *serviceNames = "default";
238
239 s_vendorFunctions_config = callbacks;
240 s_configCommands = commands;
241
242 int slotId = RIL_SOCKET_1;
243
244 pthread_rwlock_t *radioServiceRwlockPtr = getRadioServiceRwlock(0);
245 int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr);
246 assert(ret == 0);
247 RLOGD("registerConfigService: starting V1_2::IConfigRadio %s", serviceNames);
248 radioConfigService = new RadioConfigImpl;
249
250 radioConfigService->mSlotId = slotId;
251 radioConfigService->mRadioConfigResponse = NULL;
252 radioConfigService->mRadioConfigIndication = NULL;
253 radioConfigService->mRadioConfigResponseV1_1 = NULL;
254 radioConfigService->mRadioConfigResponseV1_2 = NULL;
255 radioConfigService->mRadioConfigIndicationV1_2 = NULL;
256 android::status_t status = radioConfigService->registerAsService(serviceNames);
257 RLOGD("registerConfigService registerService: status %d", status);
258 ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
259 assert(ret == 0);
260 }
261
checkReturnStatus(Return<void> & ret)262 void checkReturnStatus(Return<void>& ret) {
263 if (ret.isOk() == false) {
264 RLOGE("checkReturnStatus_config: unable to call response/indication callback");
265 // Remote process hosting the callbacks must be dead. Reset the callback objects;
266 // there's no other recovery to be done here. When the client process is back up, it will
267 // call setResponseFunctions()
268
269 // Caller should already hold rdlock, release that first
270 // note the current counter to avoid overwriting updates made by another thread before
271 // write lock is acquired.
272 int counter = mCounterRadioConfig;
273 pthread_rwlock_t *radioServiceRwlockPtr = radio_1_6::getRadioServiceRwlock(0);
274 int ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
275 assert(ret == 0);
276
277 // acquire wrlock
278 ret = pthread_rwlock_wrlock(radioServiceRwlockPtr);
279 assert(ret == 0);
280
281 // make sure the counter value has not changed
282 if (counter == mCounterRadioConfig) {
283 radioConfigService->mRadioConfigResponse = NULL;
284 radioConfigService->mRadioConfigIndication = NULL;
285 radioConfigService->mRadioConfigResponseV1_1 = NULL;
286 radioConfigService->mRadioConfigResponseV1_2 = NULL;
287 radioConfigService->mRadioConfigIndicationV1_2 = NULL;
288 mCounterRadioConfig++;
289 } else {
290 RLOGE("checkReturnStatus_config: not resetting responseFunctions as they likely "
291 "got updated on another thread");
292 }
293
294 // release wrlock
295 ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
296 assert(ret == 0);
297
298 // Reacquire rdlock
299 ret = pthread_rwlock_rdlock(radioServiceRwlockPtr);
300 assert(ret == 0);
301 }
302 }
303
checkReturnStatus_config(Return<void> & ret)304 void RadioConfigImpl::checkReturnStatus_config(Return<void>& ret) {
305 ::checkReturnStatus(ret);
306 }
307
getSimSlotsStatusResponse(int slotId,int responseType,int serial,RIL_Errno e,void * response,size_t responseLen)308 int radio_1_6::getSimSlotsStatusResponse(int slotId, int responseType, int serial,
309 RIL_Errno e, void *response, size_t responseLen) {
310 #if VDBG
311 RLOGD("getSimSlotsResponse: serial %d", serial);
312 #endif
313
314 if (radioConfigService->mRadioConfigResponse != NULL) {
315 RadioResponseInfo responseInfo = {};
316 populateResponseInfo(responseInfo, serial, responseType, e);
317 hidl_vec<SimSlotStatus> simSlotStatus = {};
318
319 if ((response == NULL) || (responseLen % sizeof(RIL_SimSlotStatus_V1_2) != 0)) {
320 RLOGE("getSimSlotsStatusResponse: Invalid response");
321 if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
322 } else {
323 RIL_SimSlotStatus_V1_2 *psimSlotStatus = ((RIL_SimSlotStatus_V1_2 *) response);
324 int num = responseLen / sizeof(RIL_SimSlotStatus_V1_2);
325 simSlotStatus.resize(num);
326 for (int i = 0; i < num; i++) {
327 simSlotStatus[i].cardState = (CardState)psimSlotStatus->base.cardState;
328 simSlotStatus[i].slotState = (SlotState)psimSlotStatus->base.slotState;
329 simSlotStatus[i].atr = convertCharPtrToHidlString(psimSlotStatus->base.atr);
330 simSlotStatus[i].logicalSlotId = psimSlotStatus->base.logicalSlotId;
331 simSlotStatus[i].iccid = convertCharPtrToHidlString(psimSlotStatus->base.iccid);
332 psimSlotStatus += 1;
333 }
334 }
335 Return<void> retStatus = radioConfigService->mRadioConfigResponse->getSimSlotsStatusResponse(
336 responseInfo, simSlotStatus);
337 radioConfigService->checkReturnStatus_config(retStatus);
338 } else {
339 RLOGE("getSimSlotsResponse: radioConfigService->mRadioConfigResponse == NULL");
340 }
341
342 return 0;
343 }
344
setSimSlotsMappingResponse(int slotId,int responseType,int serial,RIL_Errno e,void * response,size_t responseLen)345 int radio_1_6::setSimSlotsMappingResponse(int slotId, int responseType, int serial,
346 RIL_Errno e, void *response, size_t responseLen) {
347 #if VDBG
348 RLOGD("setSimSlotsMappingResponse: serial %d", serial);
349 #endif
350
351 if (radioConfigService->mRadioConfigResponse != NULL) {
352 RadioResponseInfo responseInfo = {};
353 populateResponseInfo(responseInfo, serial, responseType, e);
354 Return<void> retStatus = radioConfigService->mRadioConfigResponse->setSimSlotsMappingResponse(
355 responseInfo);
356 radioConfigService->checkReturnStatus_config(retStatus);
357 } else {
358 RLOGE("setSimSlotsMappingResponse: radioConfigService->mRadioConfigResponse == NULL");
359 }
360
361 return 0;
362 }
363
getPhoneCapabilityResponse(int slotId,int responseType,int serial,RIL_Errno e,void * response,size_t responseLen)364 int radio_1_6::getPhoneCapabilityResponse(int slotId, int responseType, int serial,
365 RIL_Errno e, void *response, size_t responseLen) {
366 #if VDBG
367 RLOGD("getPhoneCapabilityResponse: serial %d", serial);
368 #endif
369
370 if (radioConfigService->mRadioConfigResponseV1_1 != NULL) {
371 RadioResponseInfo responseInfo = {};
372 populateResponseInfo(responseInfo, serial, responseType, e);
373 V1_1::PhoneCapability phoneCapability = {};
374 if ((response == NULL) || (responseLen % sizeof(RIL_PhoneCapability) != 0)) {
375 RLOGE("getPhoneCapabilityResponse Invalid response: NULL");
376 if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
377 } else {
378 RIL_PhoneCapability *pCapability = (RIL_PhoneCapability *)response;
379 phoneCapability.maxActiveData = pCapability->maxActiveData;
380 phoneCapability.maxActiveInternetData = pCapability->maxActiveInternetData;
381 phoneCapability.isInternetLingeringSupported = pCapability->isInternetLingeringSupported;
382 phoneCapability.logicalModemList.resize(SIM_COUNT);
383 for (int i = 0 ; i < SIM_COUNT; i++) {
384 RIL_ModemInfo logicalModemInfo = pCapability->logicalModemList[i];
385 phoneCapability.logicalModemList[i].modemId = logicalModemInfo.modemId;
386 }
387 }
388 Return<void> retStatus = radioConfigService->mRadioConfigResponseV1_1->getPhoneCapabilityResponse(
389 responseInfo, phoneCapability);
390 radioConfigService->checkReturnStatus_config(retStatus);
391 } else {
392 RLOGE("getPhoneCapabilityResponse: radioConfigService->mRadioConfigResponseV1_1 == NULL");
393 }
394
395 return 0;
396 }
397
setPreferredDataModemResponse(int slotId,int responseType,int serial,RIL_Errno e,void * response,size_t responseLen)398 int radio_1_6::setPreferredDataModemResponse(int slotId, int responseType, int serial,
399 RIL_Errno e, void *response, size_t responseLen) {
400 #if VDBG
401 RLOGD("setPreferredDataModemResponse: serial %d", serial);
402 #endif
403
404 if (radioConfigService->mRadioConfigResponseV1_1 != NULL) {
405 RadioResponseInfo responseInfo = {};
406 populateResponseInfo(responseInfo, serial, responseType, e);
407 Return<void> retStatus = radioConfigService->mRadioConfigResponseV1_1->setPreferredDataModemResponse(
408 responseInfo);
409 radioConfigService->checkReturnStatus_config(retStatus);
410 } else {
411 RLOGE("setPreferredDataModemResponse: radioConfigService->mRadioConfigResponseV1_1 == NULL");
412 }
413
414 return 0;
415 }
416
setModemsConfigResponse(int slotId,int responseType,int serial,RIL_Errno e,void * response,size_t responseLen)417 int radio_1_6::setModemsConfigResponse(int slotId, int responseType, int serial,
418 RIL_Errno e, void *response, size_t responseLen) {
419 #if VDBG
420 RLOGD("setModemsConfigResponse: serial %d", serial);
421 #endif
422
423 if (radioConfigService->mRadioConfigResponseV1_1 != NULL) {
424 RadioResponseInfo responseInfo = {};
425 populateResponseInfo(responseInfo, serial, responseType, e);
426 Return<void> retStatus = radioConfigService->mRadioConfigResponseV1_1->setModemsConfigResponse(
427 responseInfo);
428 radioConfigService->checkReturnStatus_config(retStatus);
429 } else {
430 RLOGE("setModemsConfigResponse: radioConfigService->mRadioConfigResponseV1_1 == NULL");
431 }
432
433 return 0;
434 }
435
getModemsConfigResponse(int slotId,int responseType,int serial,RIL_Errno e,void * response,size_t responseLen)436 int radio_1_6::getModemsConfigResponse(int slotId, int responseType, int serial,
437 RIL_Errno e, void *response, size_t responseLen) {
438 #if VDBG
439 RLOGD("getModemsConfigResponse: serial %d", serial);
440 #endif
441
442 if (radioConfigService->mRadioConfigResponseV1_1 != NULL) {
443 RadioResponseInfo responseInfo = {};
444 populateResponseInfo(responseInfo, serial, responseType, e);
445 V1_1::ModemsConfig mdCfg = {};
446 RIL_ModemConfig *pMdCfg = (RIL_ModemConfig *)response;
447 if ((response == NULL) || (responseLen != sizeof(RIL_ModemConfig))) {
448 RLOGE("getModemsConfigResponse Invalid response: NULL");
449 if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
450 } else {
451 mdCfg.numOfLiveModems = pMdCfg->numOfLiveModems;
452 }
453 Return<void> retStatus = radioConfigService->mRadioConfigResponseV1_1->getModemsConfigResponse(
454 responseInfo, mdCfg);
455 radioConfigService->checkReturnStatus_config(retStatus);
456 } else {
457 RLOGE("getModemsConfigResponse: radioConfigService->mRadioConfigResponseV1_1 == NULL");
458 }
459
460 return 0;
461 }
462
simSlotsStatusChanged(int slotId,int indicationType,int token,RIL_Errno e,void * response,size_t responseLen)463 int radio_1_6::simSlotsStatusChanged(int slotId, int indicationType, int token, RIL_Errno e,
464 void *response, size_t responseLen) {
465 if (radioConfigService != NULL &&
466 (radioConfigService->mRadioConfigIndication != NULL ||
467 radioConfigService->mRadioConfigIndicationV1_2 != NULL)) {
468 if ((response == NULL) || (responseLen % sizeof(RIL_SimSlotStatus_V1_2) != 0)) {
469 RLOGE("simSlotsStatusChanged: invalid response");
470 return 0;
471 }
472
473 RIL_SimSlotStatus_V1_2 *psimSlotStatus = ((RIL_SimSlotStatus_V1_2 *)response);
474 int num = responseLen / sizeof(RIL_SimSlotStatus_V1_2);
475 if (radioConfigService->mRadioConfigIndication != NULL) {
476 hidl_vec<SimSlotStatus> simSlotStatus = {};
477 simSlotStatus.resize(num);
478 for (int i = 0; i < num; i++) {
479 simSlotStatus[i].cardState = (CardState) psimSlotStatus->base.cardState;
480 simSlotStatus[i].slotState = (SlotState) psimSlotStatus->base.slotState;
481 simSlotStatus[i].atr = convertCharPtrToHidlString(psimSlotStatus->base.atr);
482 simSlotStatus[i].logicalSlotId = psimSlotStatus->base.logicalSlotId;
483 simSlotStatus[i].iccid = convertCharPtrToHidlString(psimSlotStatus->base.iccid);
484 #if VDBG
485 RLOGD("simSlotsStatusChanged: cardState %d slotState %d", simSlotStatus[i].cardState,
486 simSlotStatus[i].slotState);
487 #endif
488 psimSlotStatus += 1;
489 }
490
491 Return<void> retStatus = radioConfigService->mRadioConfigIndication->simSlotsStatusChanged(
492 convertIntToRadioIndicationType(indicationType), simSlotStatus);
493 radioConfigService->checkReturnStatus_config(retStatus);
494 } else if (radioConfigService->mRadioConfigIndicationV1_2) {
495 hidl_vec<V1_2::SimSlotStatus> simSlotStatus;
496 simSlotStatus.resize(num);
497 for (int i = 0; i < num; i++) {
498 simSlotStatus[i].base.cardState = (CardState)(psimSlotStatus->base.cardState);
499 simSlotStatus[i].base.slotState = (SlotState) psimSlotStatus->base.slotState;
500 simSlotStatus[i].base.atr = convertCharPtrToHidlString(psimSlotStatus->base.atr);
501 simSlotStatus[i].base.logicalSlotId = psimSlotStatus->base.logicalSlotId;
502 simSlotStatus[i].base.iccid = convertCharPtrToHidlString(psimSlotStatus->base.iccid);
503 simSlotStatus[i].eid = convertCharPtrToHidlString(psimSlotStatus->eid);
504 psimSlotStatus += 1;
505 #if VDBG
506 RLOGD("simSlotsStatusChanged_1_2: cardState %d slotState %d",
507 simSlotStatus[i].base.cardState, simSlotStatus[i].base.slotState);
508 #endif
509 }
510
511 Return<void> retStatus = radioConfigService->mRadioConfigIndicationV1_2->simSlotsStatusChanged_1_2(
512 convertIntToRadioIndicationType(indicationType), simSlotStatus);
513 radioConfigService->checkReturnStatus_config(retStatus);
514 }
515 } else {
516 RLOGE("simSlotsStatusChanged: radioService->mRadioIndication == NULL");
517 }
518
519 return 0;
520 }
521