| /* |
| ** |
| ** Copyright 2020, The Android Open Source Project |
| ** |
| ** Licensed under the Apache License, Version 2.0 (the "License"); |
| ** you may not use this file except in compliance with the License. |
| ** You may obtain a copy of the License at |
| ** |
| ** http://www.apache.org/licenses/LICENSE-2.0 |
| ** |
| ** Unless required by applicable law or agreed to in writing, software |
| ** distributed under the License is distributed on an "AS IS" BASIS, |
| ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| ** See the License for the specific language governing permissions and |
| ** limitations under the License. |
| */ |
| |
| #define LOG_TAG "RILC" |
| |
| #include <android/hardware/radio/config/1.1/IRadioConfig.h> |
| #include <android/hardware/radio/config/1.2/IRadioConfigResponse.h> |
| #include <android/hardware/radio/config/1.3/IRadioConfigResponse.h> |
| #include <android/hardware/radio/config/1.3/IRadioConfig.h> |
| #include <android/hardware/radio/config/1.2/IRadioConfigIndication.h> |
| #include <android/hardware/radio/1.1/types.h> |
| |
| #include <ril.h> |
| #include <guest/hals/ril/reference-libril/ril_service.h> |
| #include <hidl/HidlTransportSupport.h> |
| |
| using namespace android::hardware::radio::V1_0; |
| using namespace android::hardware::radio::config; |
| using namespace android::hardware::radio::config::V1_0; |
| using namespace android::hardware::radio::config::V1_3; |
| using ::android::hardware::configureRpcThreadpool; |
| using ::android::hardware::joinRpcThreadpool; |
| using ::android::hardware::Return; |
| using ::android::hardware::hidl_string; |
| using ::android::hardware::hidl_vec; |
| using ::android::hardware::Void; |
| using android::CommandInfo; |
| using android::RequestInfo; |
| using android::requestToString; |
| using android::sp; |
| |
| RIL_RadioFunctions *s_vendorFunctions_config = NULL; |
| static CommandInfo *s_configCommands; |
| struct RadioConfigImpl; |
| sp<RadioConfigImpl> radioConfigService; |
| volatile int32_t mCounterRadioConfig; |
| |
| #if defined (ANDROID_MULTI_SIM) |
| #define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c), (d)) |
| #define CALL_ONREQUEST(a, b, c, d, e) s_vendorFunctions_config->onRequest((a), (b), (c), (d), (e)) |
| #define CALL_ONSTATEREQUEST(a) s_vendorFunctions_config->onStateRequest(a) |
| #else |
| #define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c)) |
| #define CALL_ONREQUEST(a, b, c, d, e) s_vendorFunctions_config->onRequest((a), (b), (c), (d)) |
| #define CALL_ONSTATEREQUEST(a) s_vendorFunctions_config->onStateRequest() |
| #endif |
| |
| extern void populateResponseInfo(RadioResponseInfo& responseInfo, int serial, int responseType, |
| RIL_Errno e); |
| |
| extern void populateResponseInfo_1_6( |
| ::android::hardware::radio::V1_6::RadioResponseInfo &responseInfo, |
| int serial, int responseType, RIL_Errno e); |
| |
| extern bool dispatchVoid(int serial, int slotId, int request); |
| extern bool dispatchString(int serial, int slotId, int request, const char * str); |
| extern bool dispatchStrings(int serial, int slotId, int request, bool allowEmpty, |
| int countStrings, ...); |
| extern bool dispatchInts(int serial, int slotId, int request, int countInts, ...); |
| extern hidl_string convertCharPtrToHidlString(const char *ptr); |
| extern void sendErrorResponse(android::RequestInfo *pRI, RIL_Errno err); |
| extern RadioIndicationType convertIntToRadioIndicationType(int indicationType); |
| |
| extern bool isChangeSlotId(int serviceId, int slotId); |
| |
| struct RadioConfigImpl : public V1_3::IRadioConfig { |
| int32_t mSlotId; |
| sp<V1_0::IRadioConfigResponse> mRadioConfigResponse; |
| sp<V1_0::IRadioConfigIndication> mRadioConfigIndication; |
| sp<V1_1::IRadioConfigResponse> mRadioConfigResponseV1_1; |
| sp<V1_2::IRadioConfigResponse> mRadioConfigResponseV1_2; |
| sp<V1_2::IRadioConfigIndication> mRadioConfigIndicationV1_2; |
| sp<V1_3::IRadioConfigResponse> mRadioConfigResponseV1_3; |
| |
| Return<void> setResponseFunctions( |
| const ::android::sp<V1_0::IRadioConfigResponse>& radioConfigResponse, |
| const ::android::sp<V1_0::IRadioConfigIndication>& radioConfigIndication); |
| |
| Return<void> getSimSlotsStatus(int32_t serial); |
| |
| Return<void> setSimSlotsMapping(int32_t serial, const hidl_vec<uint32_t>& slotMap); |
| |
| Return<void> getPhoneCapability(int32_t serial); |
| |
| Return<void> setPreferredDataModem(int32_t serial, uint8_t modemId); |
| |
| Return<void> setModemsConfig(int32_t serial, const V1_1::ModemsConfig& modemsConfig); |
| |
| Return<void> getModemsConfig(int32_t serial); |
| |
| Return<void> getHalDeviceCapabilities(int32_t serial); |
| |
| void checkReturnStatus_config(Return<void>& ret); |
| }; |
| Return<void> RadioConfigImpl::setResponseFunctions( |
| const ::android::sp<V1_0::IRadioConfigResponse>& radioConfigResponse, |
| const ::android::sp<V1_0::IRadioConfigIndication>& radioConfigIndication) { |
| pthread_rwlock_t *radioServiceRwlockPtr = radio_1_6::getRadioServiceRwlock(RIL_SOCKET_1); |
| int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); |
| assert(ret == 0); |
| |
| mRadioConfigResponse = radioConfigResponse; |
| mRadioConfigIndication = radioConfigIndication; |
| |
| |
| mRadioConfigResponseV1_1 = |
| V1_1::IRadioConfigResponse::castFrom(mRadioConfigResponse).withDefault(nullptr); |
| if (mRadioConfigResponseV1_1 == nullptr) { |
| mRadioConfigResponseV1_1 = nullptr; |
| } |
| |
| mRadioConfigResponseV1_2 = |
| V1_2::IRadioConfigResponse::castFrom(mRadioConfigResponse).withDefault(nullptr); |
| mRadioConfigIndicationV1_2 = |
| V1_2::IRadioConfigIndication::castFrom(mRadioConfigIndication).withDefault(nullptr); |
| if (mRadioConfigResponseV1_2 == nullptr || mRadioConfigIndicationV1_2 == nullptr) { |
| mRadioConfigResponseV1_2 = nullptr; |
| mRadioConfigIndicationV1_2 = nullptr; |
| } |
| |
| mRadioConfigResponseV1_3 = |
| V1_3::IRadioConfigResponse::castFrom(mRadioConfigResponse).withDefault(nullptr); |
| if (mRadioConfigResponseV1_3 == nullptr || mRadioConfigResponseV1_3 == nullptr) { |
| mRadioConfigResponseV1_3 = nullptr; |
| } |
| |
| mCounterRadioConfig++; |
| |
| ret = pthread_rwlock_unlock(radioServiceRwlockPtr); |
| assert(ret == 0); |
| |
| return Void(); |
| } |
| |
| Return<void> RadioConfigImpl::getSimSlotsStatus(int32_t serial) { |
| #if VDBG |
| RLOGD("getSimSlotsStatus: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFIG_GET_SLOT_STATUS); |
| |
| return Void(); |
| } |
| |
| Return<void> RadioConfigImpl::setSimSlotsMapping(int32_t serial, const hidl_vec<uint32_t>& slotMap) { |
| #if VDBG |
| RLOGD("setSimSlotsMapping: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, RIL_SOCKET_1, |
| RIL_REQUEST_CONFIG_SET_SLOT_MAPPING); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| size_t slotNum = slotMap.size(); |
| |
| if (slotNum > RIL_SOCKET_NUM) { |
| RLOGE("setSimSlotsMapping: invalid parameter"); |
| sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); |
| return Void(); |
| } |
| |
| for (size_t socket_id = 0; socket_id < slotNum; socket_id++) { |
| if (slotMap[socket_id] >= RIL_SOCKET_NUM) { |
| RLOGE("setSimSlotsMapping: invalid parameter[%zu]", socket_id); |
| sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); |
| return Void(); |
| } |
| // confirm logical id is not duplicate |
| for (size_t nextId = socket_id + 1; nextId < slotNum; nextId++) { |
| if (slotMap[socket_id] == slotMap[nextId]) { |
| RLOGE("setSimSlotsMapping: slot parameter is the same:[%zu] and [%zu]", |
| socket_id, nextId); |
| sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); |
| return Void(); |
| } |
| } |
| } |
| int *pSlotMap = (int *)calloc(slotNum, sizeof(int)); |
| |
| for (size_t socket_id = 0; socket_id < slotNum; socket_id++) { |
| pSlotMap[socket_id] = slotMap[socket_id]; |
| } |
| |
| CALL_ONREQUEST(RIL_REQUEST_CONFIG_SET_SLOT_MAPPING, pSlotMap, |
| slotNum * sizeof(int), pRI, pRI->socket_id); |
| if (pSlotMap != NULL) { |
| free(pSlotMap); |
| } |
| |
| return Void(); |
| } |
| |
| Return<void> RadioConfigImpl::getPhoneCapability(int32_t serial) { |
| #if VDBG |
| RLOGD("getPhoneCapability: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFIG_GET_PHONE_CAPABILITY); |
| return Void(); |
| } |
| |
| Return<void> RadioConfigImpl::setPreferredDataModem(int32_t serial, uint8_t modemId) { |
| #if VDBG |
| RLOGD("setPreferredDataModem: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_CONFIG_SET_PREFER_DATA_MODEM, 1, modemId); |
| return Void(); |
| } |
| |
| Return<void> RadioConfigImpl::setModemsConfig(int32_t serial, const V1_1::ModemsConfig& modemsConfig) { |
| #if VDBG |
| RLOGD("setModemsConfig: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, |
| RIL_REQUEST_CONFIG_SET_MODEM_CONFIG); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| RIL_ModemConfig mdConfig = {}; |
| |
| mdConfig.numOfLiveModems = modemsConfig.numOfLiveModems; |
| |
| |
| CALL_ONREQUEST(RIL_REQUEST_CONFIG_SET_MODEM_CONFIG, &mdConfig, |
| sizeof(RIL_ModemConfig), pRI, pRI->socket_id); |
| |
| return Void(); |
| } |
| |
| Return<void> RadioConfigImpl::getModemsConfig(int32_t serial) { |
| #if VDBG |
| RLOGD("getModemsConfig: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFIG_GET_MODEM_CONFIG); |
| return Void(); |
| } |
| |
| Return<void> RadioConfigImpl::getHalDeviceCapabilities(int32_t serial) { |
| #if VDBG |
| RLOGD("getHalDeviceCapabilities: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFIG_GET_HAL_DEVICE_CAPABILITIES); |
| return Void(); |
| } |
| |
| void radio_1_6::registerConfigService(RIL_RadioFunctions *callbacks, CommandInfo *commands) { |
| using namespace android::hardware; |
| RLOGD("Entry %s", __FUNCTION__); |
| const char *serviceNames = "default"; |
| |
| s_vendorFunctions_config = callbacks; |
| s_configCommands = commands; |
| |
| int slotId = RIL_SOCKET_1; |
| |
| pthread_rwlock_t *radioServiceRwlockPtr = getRadioServiceRwlock(0); |
| int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); |
| assert(ret == 0); |
| RLOGD("registerConfigService: starting V1_2::IConfigRadio %s", serviceNames); |
| radioConfigService = new RadioConfigImpl; |
| |
| radioConfigService->mSlotId = slotId; |
| radioConfigService->mRadioConfigResponse = NULL; |
| radioConfigService->mRadioConfigIndication = NULL; |
| radioConfigService->mRadioConfigResponseV1_1 = NULL; |
| radioConfigService->mRadioConfigResponseV1_2 = NULL; |
| radioConfigService->mRadioConfigResponseV1_3 = NULL; |
| radioConfigService->mRadioConfigIndicationV1_2 = NULL; |
| android::status_t status = radioConfigService->registerAsService(serviceNames); |
| RLOGD("registerConfigService registerService: status %d", status); |
| ret = pthread_rwlock_unlock(radioServiceRwlockPtr); |
| assert(ret == 0); |
| } |
| |
| void checkReturnStatus(Return<void>& ret) { |
| if (ret.isOk() == false) { |
| RLOGE("checkReturnStatus_config: unable to call response/indication callback"); |
| // Remote process hosting the callbacks must be dead. Reset the callback objects; |
| // there's no other recovery to be done here. When the client process is back up, it will |
| // call setResponseFunctions() |
| |
| // Caller should already hold rdlock, release that first |
| // note the current counter to avoid overwriting updates made by another thread before |
| // write lock is acquired. |
| int counter = mCounterRadioConfig; |
| pthread_rwlock_t *radioServiceRwlockPtr = radio_1_6::getRadioServiceRwlock(0); |
| int ret = pthread_rwlock_unlock(radioServiceRwlockPtr); |
| assert(ret == 0); |
| |
| // acquire wrlock |
| ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); |
| assert(ret == 0); |
| |
| // make sure the counter value has not changed |
| if (counter == mCounterRadioConfig) { |
| radioConfigService->mRadioConfigResponse = NULL; |
| radioConfigService->mRadioConfigIndication = NULL; |
| radioConfigService->mRadioConfigResponseV1_1 = NULL; |
| radioConfigService->mRadioConfigResponseV1_2 = NULL; |
| radioConfigService->mRadioConfigResponseV1_3 = NULL; |
| radioConfigService->mRadioConfigIndicationV1_2 = NULL; |
| mCounterRadioConfig++; |
| } else { |
| RLOGE("checkReturnStatus_config: not resetting responseFunctions as they likely " |
| "got updated on another thread"); |
| } |
| |
| // release wrlock |
| ret = pthread_rwlock_unlock(radioServiceRwlockPtr); |
| assert(ret == 0); |
| |
| // Reacquire rdlock |
| ret = pthread_rwlock_rdlock(radioServiceRwlockPtr); |
| assert(ret == 0); |
| } |
| } |
| |
| void RadioConfigImpl::checkReturnStatus_config(Return<void>& ret) { |
| ::checkReturnStatus(ret); |
| } |
| |
| int radio_1_6::getSimSlotsStatusResponse(int slotId, int responseType, int serial, |
| RIL_Errno e, void *response, size_t responseLen) { |
| #if VDBG |
| RLOGD("getSimSlotsResponse: serial %d", serial); |
| #endif |
| |
| if (radioConfigService->mRadioConfigResponse != NULL) { |
| RadioResponseInfo responseInfo = {}; |
| populateResponseInfo(responseInfo, serial, responseType, e); |
| hidl_vec<SimSlotStatus> simSlotStatus = {}; |
| |
| if ((response == NULL) || (responseLen % sizeof(RIL_SimSlotStatus_V1_2) != 0)) { |
| RLOGE("getSimSlotsStatusResponse: Invalid response"); |
| if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; |
| } else { |
| RIL_SimSlotStatus_V1_2 *psimSlotStatus = ((RIL_SimSlotStatus_V1_2 *) response); |
| int num = responseLen / sizeof(RIL_SimSlotStatus_V1_2); |
| simSlotStatus.resize(num); |
| for (int i = 0; i < num; i++) { |
| simSlotStatus[i].cardState = (CardState)psimSlotStatus->base.cardState; |
| simSlotStatus[i].slotState = (SlotState)psimSlotStatus->base.slotState; |
| simSlotStatus[i].atr = convertCharPtrToHidlString(psimSlotStatus->base.atr); |
| simSlotStatus[i].logicalSlotId = psimSlotStatus->base.logicalSlotId; |
| simSlotStatus[i].iccid = convertCharPtrToHidlString(psimSlotStatus->base.iccid); |
| psimSlotStatus += 1; |
| } |
| } |
| Return<void> retStatus = radioConfigService->mRadioConfigResponse->getSimSlotsStatusResponse( |
| responseInfo, simSlotStatus); |
| radioConfigService->checkReturnStatus_config(retStatus); |
| } else { |
| RLOGE("getSimSlotsResponse: radioConfigService->mRadioConfigResponse == NULL"); |
| } |
| |
| return 0; |
| } |
| |
| int radio_1_6::setSimSlotsMappingResponse(int slotId, int responseType, int serial, |
| RIL_Errno e, void *response, size_t responseLen) { |
| #if VDBG |
| RLOGD("setSimSlotsMappingResponse: serial %d", serial); |
| #endif |
| |
| if (radioConfigService->mRadioConfigResponse != NULL) { |
| RadioResponseInfo responseInfo = {}; |
| populateResponseInfo(responseInfo, serial, responseType, e); |
| Return<void> retStatus = radioConfigService->mRadioConfigResponse->setSimSlotsMappingResponse( |
| responseInfo); |
| radioConfigService->checkReturnStatus_config(retStatus); |
| } else { |
| RLOGE("setSimSlotsMappingResponse: radioConfigService->mRadioConfigResponse == NULL"); |
| } |
| |
| return 0; |
| } |
| |
| int radio_1_6::getPhoneCapabilityResponse(int slotId, int responseType, int serial, |
| RIL_Errno e, void *response, size_t responseLen) { |
| #if VDBG |
| RLOGD("getPhoneCapabilityResponse: serial %d", serial); |
| #endif |
| |
| if (radioConfigService->mRadioConfigResponseV1_1 != NULL) { |
| RadioResponseInfo responseInfo = {}; |
| populateResponseInfo(responseInfo, serial, responseType, e); |
| V1_1::PhoneCapability phoneCapability = {}; |
| if ((response == NULL) || (responseLen % sizeof(RIL_PhoneCapability) != 0)) { |
| RLOGE("getPhoneCapabilityResponse Invalid response: NULL"); |
| if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; |
| } else { |
| RIL_PhoneCapability *pCapability = (RIL_PhoneCapability *)response; |
| phoneCapability.maxActiveData = pCapability->maxActiveData; |
| phoneCapability.maxActiveInternetData = pCapability->maxActiveInternetData; |
| phoneCapability.isInternetLingeringSupported = pCapability->isInternetLingeringSupported; |
| phoneCapability.logicalModemList.resize(SIM_COUNT); |
| for (int i = 0 ; i < SIM_COUNT; i++) { |
| RIL_ModemInfo logicalModemInfo = pCapability->logicalModemList[i]; |
| phoneCapability.logicalModemList[i].modemId = logicalModemInfo.modemId; |
| } |
| } |
| Return<void> retStatus = radioConfigService->mRadioConfigResponseV1_1->getPhoneCapabilityResponse( |
| responseInfo, phoneCapability); |
| radioConfigService->checkReturnStatus_config(retStatus); |
| } else { |
| RLOGE("getPhoneCapabilityResponse: radioConfigService->mRadioConfigResponseV1_1 == NULL"); |
| } |
| |
| return 0; |
| } |
| |
| int radio_1_6::setPreferredDataModemResponse(int slotId, int responseType, int serial, |
| RIL_Errno e, void *response, size_t responseLen) { |
| #if VDBG |
| RLOGD("setPreferredDataModemResponse: serial %d", serial); |
| #endif |
| |
| if (radioConfigService->mRadioConfigResponseV1_1 != NULL) { |
| RadioResponseInfo responseInfo = {}; |
| populateResponseInfo(responseInfo, serial, responseType, e); |
| Return<void> retStatus = radioConfigService->mRadioConfigResponseV1_1->setPreferredDataModemResponse( |
| responseInfo); |
| radioConfigService->checkReturnStatus_config(retStatus); |
| } else { |
| RLOGE("setPreferredDataModemResponse: radioConfigService->mRadioConfigResponseV1_1 == NULL"); |
| } |
| |
| return 0; |
| } |
| |
| int radio_1_6::setModemsConfigResponse(int slotId, int responseType, int serial, |
| RIL_Errno e, void *response, size_t responseLen) { |
| #if VDBG |
| RLOGD("setModemsConfigResponse: serial %d", serial); |
| #endif |
| |
| if (radioConfigService->mRadioConfigResponseV1_1 != NULL) { |
| RadioResponseInfo responseInfo = {}; |
| populateResponseInfo(responseInfo, serial, responseType, e); |
| Return<void> retStatus = radioConfigService->mRadioConfigResponseV1_1->setModemsConfigResponse( |
| responseInfo); |
| radioConfigService->checkReturnStatus_config(retStatus); |
| } else { |
| RLOGE("setModemsConfigResponse: radioConfigService->mRadioConfigResponseV1_1 == NULL"); |
| } |
| |
| return 0; |
| } |
| |
| int radio_1_6::getModemsConfigResponse(int slotId, int responseType, int serial, |
| RIL_Errno e, void *response, size_t responseLen) { |
| #if VDBG |
| RLOGD("getModemsConfigResponse: serial %d", serial); |
| #endif |
| |
| if (radioConfigService->mRadioConfigResponseV1_1 != NULL) { |
| RadioResponseInfo responseInfo = {}; |
| populateResponseInfo(responseInfo, serial, responseType, e); |
| V1_1::ModemsConfig mdCfg = {}; |
| RIL_ModemConfig *pMdCfg = (RIL_ModemConfig *)response; |
| if ((response == NULL) || (responseLen != sizeof(RIL_ModemConfig))) { |
| RLOGE("getModemsConfigResponse Invalid response: NULL"); |
| if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; |
| } else { |
| mdCfg.numOfLiveModems = pMdCfg->numOfLiveModems; |
| } |
| Return<void> retStatus = radioConfigService->mRadioConfigResponseV1_1->getModemsConfigResponse( |
| responseInfo, mdCfg); |
| radioConfigService->checkReturnStatus_config(retStatus); |
| } else { |
| RLOGE("getModemsConfigResponse: radioConfigService->mRadioConfigResponseV1_1 == NULL"); |
| } |
| |
| return 0; |
| } |
| |
| int radio_1_6::getHalDeviceCapabilitiesResponse(int slotId, int responseType, int serial, |
| RIL_Errno e, void *response, size_t responseLen) { |
| #if VDBG |
| RLOGD("getHalDeviceCapabilitiesResponse: serial %d", serial); |
| #endif |
| |
| if (radioConfigService->mRadioConfigResponseV1_3 != NULL) { |
| ::android::hardware::radio::V1_6::RadioResponseInfo responseInfo = {}; |
| populateResponseInfo_1_6(responseInfo, serial, responseType, e); |
| |
| bool modemReducedFeatureSet1 = false; |
| if (response == NULL || responseLen != sizeof(bool)) { |
| RLOGE("getHalDeviceCapabilitiesResponse Invalid response."); |
| } else { |
| modemReducedFeatureSet1 = (*((bool *) response)); |
| } |
| |
| Return<void> retStatus = radioConfigService->mRadioConfigResponseV1_3->getHalDeviceCapabilitiesResponse( |
| responseInfo, modemReducedFeatureSet1); |
| radioConfigService->checkReturnStatus_config(retStatus); |
| } else { |
| RLOGE("getHalDeviceCapabilitiesResponse: radioConfigService->getHalDeviceCapabilities == NULL"); |
| } |
| |
| return 0; |
| } |
| |
| int radio_1_6::simSlotsStatusChanged(int slotId, int indicationType, int token, RIL_Errno e, |
| void *response, size_t responseLen) { |
| if (radioConfigService != NULL && |
| (radioConfigService->mRadioConfigIndication != NULL || |
| radioConfigService->mRadioConfigIndicationV1_2 != NULL)) { |
| if ((response == NULL) || (responseLen % sizeof(RIL_SimSlotStatus_V1_2) != 0)) { |
| RLOGE("simSlotsStatusChanged: invalid response"); |
| return 0; |
| } |
| |
| RIL_SimSlotStatus_V1_2 *psimSlotStatus = ((RIL_SimSlotStatus_V1_2 *)response); |
| int num = responseLen / sizeof(RIL_SimSlotStatus_V1_2); |
| if (radioConfigService->mRadioConfigIndication != NULL) { |
| hidl_vec<SimSlotStatus> simSlotStatus = {}; |
| simSlotStatus.resize(num); |
| for (int i = 0; i < num; i++) { |
| simSlotStatus[i].cardState = (CardState) psimSlotStatus->base.cardState; |
| simSlotStatus[i].slotState = (SlotState) psimSlotStatus->base.slotState; |
| simSlotStatus[i].atr = convertCharPtrToHidlString(psimSlotStatus->base.atr); |
| simSlotStatus[i].logicalSlotId = psimSlotStatus->base.logicalSlotId; |
| simSlotStatus[i].iccid = convertCharPtrToHidlString(psimSlotStatus->base.iccid); |
| #if VDBG |
| RLOGD("simSlotsStatusChanged: cardState %d slotState %d", simSlotStatus[i].cardState, |
| simSlotStatus[i].slotState); |
| #endif |
| psimSlotStatus += 1; |
| } |
| |
| Return<void> retStatus = radioConfigService->mRadioConfigIndication->simSlotsStatusChanged( |
| convertIntToRadioIndicationType(indicationType), simSlotStatus); |
| radioConfigService->checkReturnStatus_config(retStatus); |
| } else if (radioConfigService->mRadioConfigIndicationV1_2) { |
| hidl_vec<V1_2::SimSlotStatus> simSlotStatus; |
| simSlotStatus.resize(num); |
| for (int i = 0; i < num; i++) { |
| simSlotStatus[i].base.cardState = (CardState)(psimSlotStatus->base.cardState); |
| simSlotStatus[i].base.slotState = (SlotState) psimSlotStatus->base.slotState; |
| simSlotStatus[i].base.atr = convertCharPtrToHidlString(psimSlotStatus->base.atr); |
| simSlotStatus[i].base.logicalSlotId = psimSlotStatus->base.logicalSlotId; |
| simSlotStatus[i].base.iccid = convertCharPtrToHidlString(psimSlotStatus->base.iccid); |
| simSlotStatus[i].eid = convertCharPtrToHidlString(psimSlotStatus->eid); |
| psimSlotStatus += 1; |
| #if VDBG |
| RLOGD("simSlotsStatusChanged_1_2: cardState %d slotState %d", |
| simSlotStatus[i].base.cardState, simSlotStatus[i].base.slotState); |
| #endif |
| } |
| |
| Return<void> retStatus = radioConfigService->mRadioConfigIndicationV1_2->simSlotsStatusChanged_1_2( |
| convertIntToRadioIndicationType(indicationType), simSlotStatus); |
| radioConfigService->checkReturnStatus_config(retStatus); |
| } |
| } else { |
| RLOGE("simSlotsStatusChanged: radioService->mRadioIndication == NULL"); |
| } |
| |
| return 0; |
| } |