• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "cellular_call_config.h"
17 
18 #include "cellular_call_data_struct.h"
19 #include "cellular_call_hisysevent.h"
20 #include "cellular_call_rdb_helper.h"
21 #include "cellular_call_register.h"
22 #include "cellular_call_service.h"
23 #include "core_manager_inner.h"
24 #include "core_service_client.h"
25 #include "module_service_utils.h"
26 #include "parameters.h"
27 #include "standardize_utils.h"
28 #include "string_ex.h"
29 #include "telephony_types.h"
30 #include "network_search_types.h"
31 
32 namespace OHOS {
33 namespace Telephony {
34 const int32_t SIM_PRESENT = 1;
35 const int32_t SIM_ABSENT = 0;
36 const int32_t IMS_SWITCH_STATUS_UNKNOWN = -1;
37 const int32_t IMS_SWITCH_STATUS_OFF = 0;
38 const int32_t IMS_SWITCH_STATUS_ON = 1;
39 const int32_t VONR_SWITCH_STATUS_UNKNOWN = -1;
40 const int32_t VONR_SWITCH_STATUS_OFF = 0;
41 const int32_t VONR_SWITCH_STATUS_ON = 1;
42 const int32_t SAVE_IMS_SWITCH_FAILED = 0;
43 const int32_t SAVE_IMS_SWITCH_SUCCESS_CHANGED = 1;
44 const int32_t SAVE_IMS_SWITCH_SUCCESS_NOT_CHANGED = 2;
45 const int32_t INVALID_SIM_ID = 0;
46 const int32_t IMS_GBA_BIT = 0x02;
47 const int32_t SYSTEM_PARAMETER_LENGTH = 0x02;
48 const int MCC_LEN = 3;
49 const std::string LAST_ICCID_KEY = "persist.telephony.last_iccid";
50 const std::string IMSSWITCH_STATE = "persist.telephony.imsswitch";
51 const std::string VONR_STATE = "persist.telephony.vonrswitch";
52 
53 std::map<int32_t, int32_t> CellularCallConfig::modeMap_;
54 std::map<int32_t, int32_t> CellularCallConfig::modeTempMap_;
55 std::map<int32_t, bool> CellularCallConfig::imsSwitchOnByDefault_;
56 std::map<int32_t, bool> CellularCallConfig::hideImsSwitch_;
57 std::map<int32_t, bool> CellularCallConfig::volteSupported_;
58 std::map<int32_t, bool> CellularCallConfig::carrierVtAvailable_;
59 std::map<int32_t, std::vector<int32_t>> CellularCallConfig::nrModeSupportedList_;
60 std::map<int32_t, bool> CellularCallConfig::volteProvisioningSupported_;
61 std::map<int32_t, bool> CellularCallConfig::ssOverUtSupported_;
62 std::map<int32_t, bool> CellularCallConfig::imsGbaRequired_;
63 std::map<int32_t, bool> CellularCallConfig::utProvisioningSupported_;
64 std::map<int32_t, bool> CellularCallConfig::imsPreferForEmergency_;
65 std::map<int32_t, int32_t> CellularCallConfig::callWaitingServiceClass_;
66 std::map<int32_t, std::vector<std::string>> CellularCallConfig::imsCallDisconnectResoninfoMapping_;
67 std::map<int32_t, bool> CellularCallConfig::forceVolteSwitchOn_;
68 std::map<int32_t, bool> CellularCallConfig::videoCallWaiting_;
69 std::map<int32_t, int32_t> CellularCallConfig::vonrSwithStatus_;
70 std::shared_mutex CellularCallConfig::mutex_;
71 std::mutex CellularCallConfig::operatorMutex_;
72 std::shared_mutex CellularCallConfig::simStateLock_;
73 std::map<int32_t, std::vector<EmergencyCall>> CellularCallConfig::eccListRadioMap_;
74 std::vector<EmergencyCall> CellularCallConfig::eccList3gppHasSim_;
75 std::vector<EmergencyCall> CellularCallConfig::eccList3gppNoSim_;
76 std::map<int32_t, std::vector<EmergencyCall>> CellularCallConfig::allEccList_;
77 std::map<int32_t, int32_t> CellularCallConfig::simState_;
78 std::map<int32_t, std::string> CellularCallConfig::curPlmn_;
79 std::map<int32_t, CellularCallConfig::cellularNetworkState> CellularCallConfig::networkServiceState_;
80 std::map<int32_t, bool> CellularCallConfig::readyToCall_;
81 bool CellularCallConfig::isOperatorConfigInit_ = false;
82 
InitDefaultOperatorConfig()83 void CellularCallConfig::InitDefaultOperatorConfig()
84 {
85     std::lock_guard<std::mutex> lock(operatorMutex_);
86     for (int32_t i = DEFAULT_SIM_SLOT_ID; i < SIM_SLOT_COUNT; ++i) {
87         CellularCallConfig::imsSwitchOnByDefault_.insert(std::pair<int, bool>(i, false));
88         CellularCallConfig::hideImsSwitch_.insert(std::pair<int, bool>(i, false));
89         CellularCallConfig::volteSupported_.insert(std::pair<int, bool>(i, true));
90         CellularCallConfig::carrierVtAvailable_.insert(std::pair<int, bool>(i, true));
91         CellularCallConfig::nrModeSupportedList_.insert(std::pair<int, std::vector<int32_t>>(
92             i, std::vector<int32_t> { CARRIER_NR_AVAILABILITY_NSA, CARRIER_NR_AVAILABILITY_SA }));
93         CellularCallConfig::volteProvisioningSupported_.insert(std::pair<int, bool>(i, false));
94         CellularCallConfig::ssOverUtSupported_.insert(std::pair<int, bool>(i, false));
95         CellularCallConfig::imsGbaRequired_.insert(std::pair<int, bool>(i, false));
96         CellularCallConfig::utProvisioningSupported_.insert(std::pair<int, bool>(i, false));
97         CellularCallConfig::imsPreferForEmergency_.insert(std::pair<int, bool>(i, true));
98         CellularCallConfig::callWaitingServiceClass_.insert(
99             std::pair<int, int32_t>(i, DEFAULT_CALL_WAITING_SERVICE_CLASS_CONFIG));
100         CellularCallConfig::imsCallDisconnectResoninfoMapping_.insert(
101             std::pair<int, std::vector<std::string>>(i, IMS_CALL_DISCONNECT_REASONINFO_MAPPING_CONFIG));
102         CellularCallConfig::forceVolteSwitchOn_.insert(std::pair<int, bool>(i, false));
103         CellularCallConfig::readyToCall_.insert(std::pair<int, bool>(i, true));
104         CellularCallConfig::vonrSwithStatus_.insert(std::pair<int, int>(i, VONR_SWITCH_STATUS_UNKNOWN));
105         CellularCallConfig::cellularNetworkState cellularState;
106         CellularCallConfig::networkServiceState_.insert(std::pair<int, CellularCallConfig::cellularNetworkState>(i,
107             cellularState));
108         CellularCallConfig::videoCallWaiting_.insert(std::pair<int, bool>(i, false));
109     }
110 }
111 
CellularCallConfig()112 CellularCallConfig::CellularCallConfig()
113 {
114     if (!isOperatorConfigInit_) {
115         InitDefaultOperatorConfig();
116         isOperatorConfigInit_ = true;
117     }
118 }
119 
SetDomainPreferenceMode(int32_t slotId,int32_t mode)120 int32_t CellularCallConfig::SetDomainPreferenceMode(int32_t slotId, int32_t mode)
121 {
122     if (mode < DomainPreferenceMode::CS_VOICE_ONLY || mode > DomainPreferenceMode::IMS_PS_VOICE_ONLY) {
123         TELEPHONY_LOGE("SetDomainPreferenceMode return, mode out of range!");
124         return CALL_ERR_PARAMETER_OUT_OF_RANGE;
125     }
126     modeTempMap_[slotId] = mode;
127     return configRequest_.SetDomainPreferenceModeRequest(slotId, mode);
128 }
129 
GetDomainPreferenceMode(int32_t slotId)130 int32_t CellularCallConfig::GetDomainPreferenceMode(int32_t slotId)
131 {
132     return configRequest_.GetDomainPreferenceModeRequest(slotId);
133 }
134 
SetImsSwitchStatus(int32_t slotId,bool active)135 int32_t CellularCallConfig::SetImsSwitchStatus(int32_t slotId, bool active)
136 {
137     TELEPHONY_LOGI("entry, slotId:%{public}d, active:%{public}d", slotId, active);
138     if (!volteSupported_[slotId]) {
139         TELEPHONY_LOGE("Enable ims switch failed due to volte is not supported.");
140         return CALL_ERR_VOLTE_NOT_SUPPORT;
141     }
142     if (active && !IsVolteProvisioned(slotId)) {
143         TELEPHONY_LOGE("Enable ims switch failed due to volte provisioning disabled.");
144         return CALL_ERR_VOLTE_PROVISIONING_DISABLED;
145     }
146     int32_t simId = CoreManagerInner::GetInstance().GetSimId(slotId);
147     if (simId <= INVALID_SIM_ID) {
148         TELEPHONY_LOGE("failed due to invalid sim id %{public}d", simId);
149         return TELEPHONY_ERR_SLOTID_INVALID;
150     }
151 
152     int32_t ret = SaveImsSwitch(slotId, BooleanToImsSwitchValue(active));
153     if (ret == SAVE_IMS_SWITCH_FAILED) {
154         return TELEPHONY_ERR_DATABASE_WRITE_FAIL;
155     } else if (ret == SAVE_IMS_SWITCH_SUCCESS_NOT_CHANGED) {
156         return TELEPHONY_SUCCESS;
157     }
158 
159     SimState simState = SimState::SIM_STATE_UNKNOWN;
160     CoreManagerInner::GetInstance().GetSimState(slotId, simState);
161     TELEPHONY_LOGI("active: %{public}d simState : %{public}d", active, simState);
162     if (simState == SimState::SIM_STATE_LOADED || simState == SimState::SIM_STATE_READY) {
163         UpdateImsCapabilities(slotId, !active, false, INVALID_OPERATOR_CONFIG_STATE);
164     }
165     return TELEPHONY_SUCCESS;
166 }
167 
GetImsSwitchStatus(int32_t slotId,bool & enabled)168 int32_t CellularCallConfig::GetImsSwitchStatus(int32_t slotId, bool &enabled)
169 {
170     TELEPHONY_LOGD("entry, slotId: %{public}d", slotId);
171     auto itorHide = hideImsSwitch_.find(slotId);
172     if (itorHide != hideImsSwitch_.end() && itorHide->second) {
173         enabled = true;
174         return TELEPHONY_SUCCESS;
175     }
176     enabled = GetSwitchStatus(slotId);
177     return TELEPHONY_SUCCESS;
178 }
179 
GetCarrierVtConfig(int32_t slotId,bool & enabled)180 int32_t CellularCallConfig::GetCarrierVtConfig(int32_t slotId, bool &enabled)
181 {
182     TELEPHONY_LOGD("entry, slotId: %{public}d", slotId);
183     auto itorHide = carrierVtAvailable_.find(slotId);
184     if (itorHide != carrierVtAvailable_.end()) {
185         enabled = itorHide -> second;
186     } else {
187         TELEPHONY_LOGI("do not find GetCarrierVtConfig");
188         enabled = false;
189     }
190     return TELEPHONY_SUCCESS;
191 }
192 
GetCarrierVtAvailbleConfig(int32_t slotId)193 bool CellularCallConfig::GetCarrierVtAvailbleConfig(int32_t slotId)
194 {
195     if (!IsValidSlotId(slotId)) {
196         TELEPHONY_LOGE(" invalid slot id %{public}d", slotId);
197         return false;
198     }
199     return carrierVtAvailable_[slotId];
200 }
201 
SetVoNRSwitchStatus(int32_t slotId,int32_t state)202 int32_t CellularCallConfig::SetVoNRSwitchStatus(int32_t slotId, int32_t state)
203 {
204     TELEPHONY_LOGI(
205         "CellularCallConfig::SetVoNRSwitchStatus entry, slotId: %{public}d, state: %{public}d", slotId, state);
206     if (!IsVonrSupported(slotId, IsGbaValid(slotId))) {
207         TELEPHONY_LOGE("Enable VoNR switch failed due to VoNR is not supported.");
208         return TELEPHONY_ERR_FAIL;
209     }
210     SimState simState = SimState::SIM_STATE_UNKNOWN;
211     CoreManagerInner::GetInstance().GetSimState(slotId, simState);
212     if (simState == SimState::SIM_STATE_LOADED || simState == SimState::SIM_STATE_READY) {
213         configRequest_.SetVoNRSwitchStatusRequest(slotId, state);
214         vonrSwithStatus_[slotId] = state;
215         return TELEPHONY_SUCCESS;
216     }
217     return TELEPHONY_ERR_NO_SIM_CARD;
218 }
219 
GetVoNRSwitchStatus(int32_t slotId,int32_t & state)220 int32_t CellularCallConfig::GetVoNRSwitchStatus(int32_t slotId, int32_t &state)
221 {
222     if (!IsVonrSupported(slotId, IsGbaValid(slotId))) {
223         TELEPHONY_LOGE("Enable VoNR switch failed due to VoNR is not supported.");
224         state = VONR_SWITCH_STATUS_OFF;
225         return TELEPHONY_SUCCESS;
226     }
227     state = ObtainVoNRState(slotId);
228     return TELEPHONY_SUCCESS;
229 }
230 
HandleSimStateChanged(int32_t slotId)231 void CellularCallConfig::HandleSimStateChanged(int32_t slotId)
232 {
233     TELEPHONY_LOGI("CellularCallConfig::HandleSimStateChanged entry, slotId: %{public}d", slotId);
234     if (CheckAndUpdateSimState(slotId)) {
235         UpdateEccNumberList(slotId);
236     }
237 }
238 
HandleFactoryReset(int32_t slotId)239 void CellularCallConfig::HandleFactoryReset(int32_t slotId)
240 {
241     if (!IsValidSlotId(slotId)) {
242         TELEPHONY_LOGE(" invalid slot id %{public}d", slotId);
243         return;
244     }
245     bool hasSimCard = false;
246     CoreManagerInner::GetInstance().HasSimCard(slotId, hasSimCard);
247     if (!hasSimCard) {
248         TELEPHONY_LOGE("return due to no sim card");
249         return;
250     }
251     // Set VoLTE to default
252     int32_t ret = SaveImsSwitch(slotId, BooleanToImsSwitchValue(imsSwitchOnByDefault_[slotId]));
253     TELEPHONY_LOGI("Save ims switch ret: %{public}d", ret);
254     UpdateImsCapabilities(slotId, true, false, INVALID_OPERATOR_CONFIG_STATE);
255 }
256 
HandleSimRecordsLoaded(int32_t slotId)257 void CellularCallConfig::HandleSimRecordsLoaded(int32_t slotId)
258 {
259     TELEPHONY_LOGI("CellularCallConfig::HandleSimRecordsLoaded entry, slotId: %{public}d", slotId);
260     CheckAndUpdateSimState(slotId);
261     UpdateEccNumberList(slotId);
262 }
263 
HandleResidentNetworkChange(int32_t slotId,std::string plmn)264 void CellularCallConfig::HandleResidentNetworkChange(int32_t slotId, std::string plmn)
265 {
266     TELEPHONY_LOGI("CellularCallConfig::HandleResidentNetworkChange entry, slotId: %{public}d", slotId);
267     curPlmn_[slotId] = plmn;
268     CheckAndUpdateSimState(slotId);
269     UpdateEccNumberList(slotId);
270 }
271 
HandleNetworkStateChange(int32_t slotId)272 void CellularCallConfig::HandleNetworkStateChange(int32_t slotId)
273 {
274     {
275         std::lock_guard<std::mutex> lock(operatorMutex_);
276         TELEPHONY_LOGI("CellularCallConfig::HandleNetworkStateChange entry, slotId: %{public}d", slotId);
277         auto itSlotId = networkServiceState_.find(slotId);
278         if (itSlotId == networkServiceState_.end()) {
279             TELEPHONY_LOGE("slotId is not in networkServiceState_");
280             return;
281         }
282         sptr<NetworkState> networkState = nullptr;
283         CoreManagerInner::GetInstance().GetNetworkStatus(slotId, networkState);
284         if (networkState == nullptr) {
285             TELEPHONY_LOGE("networkState get failed, slotId: %{public}d", slotId);
286             return;
287         }
288         bool isInSrv = networkState->GetRegStatus() == RegServiceState::REG_STATE_IN_SERVICE ? true : false;
289         bool isRoam = networkState->IsRoaming();
290         if (networkServiceState_[slotId].isInService_ == isInSrv
291             && networkServiceState_[slotId].isRoaming_ == isRoam) {
292             TELEPHONY_LOGI("service state and roaming state are not change, slotId: %{public}d", slotId);
293             return;
294         }
295         networkServiceState_[slotId].isInService_ = isInSrv;
296         networkServiceState_[slotId].isRoaming_ = isRoam;
297     }
298     CheckAndUpdateSimState(slotId);
299     UpdateEccNumberList(slotId);
300 }
301 
GetEccListFromResult(const std::vector<EccNum> & eccVec,std::vector<std::string> & callListWithCard,std::vector<std::string> & callListNoCard)302 void CellularCallConfig::GetEccListFromResult(const std::vector<EccNum> &eccVec,
303     std::vector<std::string> &callListWithCard, std::vector<std::string> &callListNoCard)
304 {
305     if (!eccVec.empty()) {
306         std::string eccWithCard = eccVec[0].ecc_withcard;
307         callListWithCard = StandardizeUtils::Split(eccWithCard, ",");
308         std::string eccNoCard = eccVec[0].ecc_nocard;
309         callListNoCard = StandardizeUtils::Split(eccNoCard, ",");
310     }
311 }
312 
CheckHomeAndPresentState(int32_t slotId,bool & isHomeAndPresent)313 int32_t CellularCallConfig::CheckHomeAndPresentState(int32_t slotId, bool &isHomeAndPresent)
314 {
315     sptr<NetworkState> networkState = nullptr;
316     CoreManagerInner::GetInstance().GetNetworkStatus(slotId, networkState);
317     if (networkState == nullptr) {
318         TELEPHONY_LOGE("networkState get failed, slotId: %{public}d", slotId);
319         return TELEPHONY_ERR_FAIL;
320     }
321     RegServiceState regState = networkState->GetRegStatus();
322     bool isRoam = networkState->IsRoaming();
323     bool isNetworkInService = (regState == RegServiceState::REG_STATE_IN_SERVICE);
324     bool isHomeNetRegister = isNetworkInService && !isRoam;
325     bool isSimPresent = false;
326     {
327         std::shared_lock<std::shared_mutex> lock(simStateLock_);
328         isSimPresent = simState_[slotId] == SIM_PRESENT;
329     }
330     isHomeAndPresent = isHomeNetRegister && isSimPresent;
331     return TELEPHONY_SUCCESS;
332 }
333 
UpdateEccNumberList(int32_t slotId)334 void CellularCallConfig::UpdateEccNumberList(int32_t slotId)
335 {
336     std::u16string u16Hplmn = u"";
337     CoreManagerInner::GetInstance().GetSimOperatorNumeric(slotId, u16Hplmn);
338     std::string hplmn = Str16ToStr8(u16Hplmn);
339     std::vector<std::string> callListWithCard;
340     std::vector<std::string> callListNoCard;
341     std::vector<EccNum> eccVec;
342     bool isHomeAndPresent = false;
343     if (CheckHomeAndPresentState(slotId, isHomeAndPresent) != TELEPHONY_SUCCESS) {
344         return;
345     }
346     if (!hplmn.empty() && isHomeAndPresent) {
347         OperatorConfig operatorConfig;
348         CoreManagerInner::GetInstance().GetOperatorConfigs(slotId, operatorConfig);
349         callListWithCard = operatorConfig.stringArrayValue[KEY_EMERGENCY_CALL_STRING_ARRAY];
350         if (callListWithCard.empty()) {
351             DelayedSingleton<CellularCallRdbHelper>::GetInstance()->QueryEccList(hplmn, eccVec);
352             GetEccListFromResult(eccVec, callListWithCard, callListNoCard);
353         }
354     } else {
355         if (curPlmn_[slotId].empty()) {
356             std::u16string u16Rplmn = CoreManagerInner::GetInstance().GetOperatorNumeric(slotId);
357             std::string rplmn = Str16ToStr8(u16Rplmn);
358             if (rplmn.empty()) {
359                 TELEPHONY_LOGE("rplmn is empty");
360                 return;
361             }
362             curPlmn_[slotId] = rplmn;
363         }
364         DelayedSingleton<CellularCallRdbHelper>::GetInstance()->QueryEccList(curPlmn_[slotId], eccVec);
365         GetEccListFromResult(eccVec, callListWithCard, callListNoCard);
366     }
367     std::vector<EmergencyCall> eccInfoList;
368     for (auto it : callListWithCard) {
369         eccInfoList.push_back(BuildDefaultEmergencyCall(it, SimpresentType::TYPE_HAS_CARD));
370     }
371     for (auto it : callListNoCard) {
372         eccInfoList.push_back(BuildDefaultEmergencyCall(it, SimpresentType::TYPE_NO_CARD));
373     }
374     SetEmergencyCallList(slotId, eccInfoList);
375 }
376 
HandleSimAccountLoaded(int32_t slotId)377 void CellularCallConfig::HandleSimAccountLoaded(int32_t slotId)
378 {
379     TELEPHONY_LOGI("entry, slotId: %{public}d", slotId);
380     CheckAndUpdateSimState(slotId);
381     UpdateEccNumberList(slotId);
382 }
383 
HandleOperatorConfigChanged(int32_t slotId,int32_t state)384 void CellularCallConfig::HandleOperatorConfigChanged(int32_t slotId, int32_t state)
385 {
386     UpdateImsConfiguration(slotId, state, true);
387 }
388 
UpdateImsConfiguration(int32_t slotId,int32_t configState,bool isOpcChanged)389 void CellularCallConfig::UpdateImsConfiguration(int32_t slotId, int32_t configState, bool isOpcChanged)
390 {
391     OperatorConfig operatorConfig;
392     int32_t ret = CoreManagerInner::GetInstance().GetOperatorConfigs(slotId, operatorConfig);
393     if (ret != TELEPHONY_SUCCESS) {
394         TELEPHONY_LOGE("failed due to get operator config");
395         return;
396     }
397 
398     int32_t result = ParseAndCacheOperatorConfigs(slotId, operatorConfig);
399     if (result != TELEPHONY_SUCCESS) {
400         TELEPHONY_LOGE("failed due to parse operator config");
401         return;
402     }
403     saveImsSwitchStatusToLocalForPowerOn(slotId);
404     ResetImsSwitch(slotId);
405     UpdateImsCapabilities(slotId, true, isOpcChanged, configState);
406     if (videoCallWaiting_.find(slotId) != videoCallWaiting_.end()) {
407         configRequest_.SetVideoCallWaiting(slotId, videoCallWaiting_[slotId]);
408     }
409     if (carrierVtAvailable_.find(slotId) != carrierVtAvailable_.end()) {
410         configRequest_.SetCarrierVtConfigRequest(slotId, carrierVtAvailable_[slotId]);
411     }
412 }
413 
ParseAndCacheOperatorConfigs(int32_t slotId,OperatorConfig & poc)414 int32_t CellularCallConfig::ParseAndCacheOperatorConfigs(int32_t slotId, OperatorConfig &poc)
415 {
416     TELEPHONY_LOGI("CellularCallConfig::ParseAndCacheOperatorConfigs start. slotId %{public}d", slotId);
417     std::lock_guard<std::mutex> lock(operatorMutex_);
418     if (!IsValidSlotId(slotId)) {
419         TELEPHONY_LOGE(" invalid slot id %{public}d", slotId);
420         return TELEPHONY_ERROR;
421     }
422 
423     ParseBoolOperatorConfigs(slotId, imsSwitchOnByDefault_, poc, KEY_IMS_SWITCH_ON_BY_DEFAULT_BOOL);
424     ParseBoolOperatorConfigs(slotId, hideImsSwitch_, poc, KEY_HIDE_IMS_SWITCH_BOOL);
425     ParseBoolOperatorConfigs(slotId, volteSupported_, poc, KEY_VOLTE_SUPPORTED_BOOL);
426     ParseBoolOperatorConfigs(slotId, volteProvisioningSupported_, poc, KEY_VOLTE_PROVISIONING_SUPPORTED_BOOL);
427     ParseBoolOperatorConfigs(slotId, carrierVtAvailable_, poc, KEY_CARRIER_VT_AVAILABLE_BOOL);
428     ParseBoolOperatorConfigs(slotId, ssOverUtSupported_, poc, KEY_SS_OVER_UT_SUPPORTED_BOOL);
429     ParseBoolOperatorConfigs(slotId, imsGbaRequired_, poc, KEY_IMS_GBA_REQUIRED_BOOL);
430     ParseBoolOperatorConfigs(slotId, utProvisioningSupported_, poc, KEY_UT_PROVISIONING_SUPPORTED_BOOL);
431     ParseBoolOperatorConfigs(slotId, imsPreferForEmergency_, poc, KEY_IMS_PREFER_FOR_EMERGENCY_BOOL);
432     ParseBoolOperatorConfigs(slotId, forceVolteSwitchOn_, poc, KEY_FORCE_VOLTE_SWITCH_ON_BOOL);
433     ParseBoolOperatorConfigs(slotId, videoCallWaiting_, poc, KEY_VIDEO_CALL_WAITING_ON_BOOL);
434 
435     if (poc.intArrayValue.count(KEY_NR_MODE_SUPPORTED_LIST_INT_ARRAY) > 0) {
436         nrModeSupportedList_[slotId] = poc.intArrayValue[KEY_NR_MODE_SUPPORTED_LIST_INT_ARRAY];
437     }
438     if (poc.intValue.count(KEY_CALL_WAITING_SERVICE_CLASS_INT) > 0) {
439         callWaitingServiceClass_[slotId] = poc.intValue[KEY_CALL_WAITING_SERVICE_CLASS_INT];
440     }
441     if (poc.stringArrayValue.count(KEY_IMS_CALL_DISCONNECT_REASONINFO_MAPPING_STRING_ARRAY) > 0) {
442         imsCallDisconnectResoninfoMapping_[slotId] =
443             poc.stringArrayValue[KEY_IMS_CALL_DISCONNECT_REASONINFO_MAPPING_STRING_ARRAY];
444     }
445     return TELEPHONY_SUCCESS;
446 }
447 
ParseBoolOperatorConfigs(int32_t slotId,std::map<int32_t,bool> & config,OperatorConfig & poc,std::string configName)448 void CellularCallConfig::ParseBoolOperatorConfigs(
449     int32_t slotId, std::map<int32_t, bool> &config, OperatorConfig &poc, std::string configName)
450 {
451     auto it = poc.boolValue.find(configName);
452     if (it != poc.boolValue.end()) {
453         config[slotId] = it->second;
454     } else {
455         TELEPHONY_LOGE("do't find operator config %{public}s", configName.c_str());
456     }
457 }
458 
ResetImsSwitch(int32_t slotId)459 void CellularCallConfig::ResetImsSwitch(int32_t slotId)
460 {
461     bool hasSimCard = false;
462     CoreManagerInner::GetInstance().HasSimCard(slotId, hasSimCard);
463     if (!hasSimCard) {
464         TELEPHONY_LOGE("return due to no sim card");
465         return;
466     }
467     std::u16string iccId;
468     CoreManagerInner::GetInstance().GetSimIccId(slotId, iccId);
469     if (IsSimChanged(slotId, Str16ToStr8(iccId)) && forceVolteSwitchOn_[slotId]) {
470         int32_t ret = CoreManagerInner::GetInstance().SaveImsSwitch(
471             slotId, BooleanToImsSwitchValue(imsSwitchOnByDefault_[slotId]));
472         if (ret != TELEPHONY_SUCCESS) {
473             TELEPHONY_LOGE("SaveImsSwitch failed");
474         } else {
475             saveImsSwitchStatusToLocal(slotId, BooleanToImsSwitchValue(imsSwitchOnByDefault_[slotId]));
476         }
477     }
478 }
479 
UpdateImsCapabilities(int32_t slotId,bool needUpdateUtCapability,bool isOperatorConfigChanged,int32_t state)480 void CellularCallConfig::UpdateImsCapabilities(int32_t slotId, bool needUpdateUtCapability,
481     bool isOperatorConfigChanged, int32_t state)
482 {
483     ImsCapabilityList imsCapabilityList;
484     TELEPHONY_LOGI("UpdateImsCapabilities entry, slotId is %{public}d", slotId);
485     UpdateImsVoiceCapabilities(slotId, imsCapabilityList);
486     if (isOperatorConfigChanged) {
487         configRequest_.NotifyOperatorConfigChanged(slotId, state);
488     }
489     if (needUpdateUtCapability) {
490         UpdateImsUtCapabilities(slotId, imsCapabilityList);
491     }
492     configRequest_.UpdateImsCapabilities(slotId, imsCapabilityList);
493     configRequest_.SetImsSwitchStatusRequest(slotId, IsNeedTurnOnIms(imsCapabilityList));
494 }
IsGbaValid(int32_t slotId)495 bool CellularCallConfig::IsGbaValid(int32_t slotId)
496 {
497     if (imsGbaRequired_[slotId]) {
498         std::u16string simist = CoreManagerInner::GetInstance().GetSimIst(slotId);
499         std::string simistStr = Str16ToStr8(simist);
500         // If carrier requires that IMS is only available if GBA capable SIM is used,
501         // then this function checks GBA bit in EF IST.
502         // Format of EF IST is defined in 3GPP TS 31.103 (Section 4.2.7).
503         if (!simistStr.empty() && simistStr.length() > 1) {
504             bool result = (IMS_GBA_BIT & simistStr.at(1)) != 0;
505             return result;
506         }
507     }
508     return true;
509 }
510 
UpdateImsVoiceCapabilities(int32_t slotId,ImsCapabilityList & imsCapabilityList)511 void CellularCallConfig::UpdateImsVoiceCapabilities(int32_t slotId, ImsCapabilityList &imsCapabilityList)
512 {
513     ImsCapability vonrCapability;
514     vonrCapability.imsCapabilityType = ImsCapabilityType::CAPABILITY_TYPE_VOICE;
515     vonrCapability.imsRadioTech = ImsRegTech::IMS_REG_TECH_NR;
516     vonrCapability.enable = IsVonrSupportedForImsSwitch(slotId, IsGbaValid(slotId));
517     imsCapabilityList.imsCapabilities.push_back(vonrCapability);
518 
519     ImsCapability volteCapability;
520     volteCapability.imsCapabilityType = ImsCapabilityType::CAPABILITY_TYPE_VOICE;
521     volteCapability.imsRadioTech = ImsRegTech::IMS_REG_TECH_LTE;
522     volteCapability.enable = IsVolteSupport(slotId);
523     imsCapabilityList.imsCapabilities.push_back(volteCapability);
524     TELEPHONY_LOGI("slotId = %{public}d, vonrCapability = %{public}d, volteCapability = %{public}d,",
525         slotId, vonrCapability.enable, volteCapability.enable);
526 }
527 
UpdateImsUtCapabilities(int32_t slotId,ImsCapabilityList & imsCapabilityList)528 void CellularCallConfig::UpdateImsUtCapabilities(int32_t slotId, ImsCapabilityList &imsCapabilityList)
529 {
530     bool isGbaValid = IsGbaValid(slotId);
531     ImsCapability utCapability;
532     utCapability.imsCapabilityType = ImsCapabilityType::CAPABILITY_TYPE_UT;
533     utCapability.imsRadioTech = ImsRegTech::IMS_REG_TECH_LTE;
534     utCapability.enable = ssOverUtSupported_[slotId] && isGbaValid && IsUtProvisioned(slotId);
535     imsCapabilityList.imsCapabilities.push_back(utCapability);
536 }
537 
IsVolteProvisioned(int32_t slotId)538 bool CellularCallConfig::IsVolteProvisioned(int32_t slotId)
539 {
540     if (volteProvisioningSupported_[slotId]) {
541         int32_t volteFeatureValue;
542         int32_t result = configRequest_.GetImsFeatureValueRequest(FeatureType::TYPE_VOICE_OVER_LTE, volteFeatureValue);
543         if (result != TELEPHONY_SUCCESS) {
544             TELEPHONY_LOGE("get volte feature value failed");
545             return false;
546         }
547         return volteFeatureValue == ImsFeatureIntResult::IMS_FEATURE_INT_VALUE_ENABLED;
548     }
549     return true;
550 }
551 
IsVonrSupported(int32_t slotId,bool isGbaValid)552 bool CellularCallConfig::IsVonrSupported(int32_t slotId, bool isGbaValid)
553 {
554     if (std::find(nrModeSupportedList_[slotId].begin(), nrModeSupportedList_[slotId].end(),
555         CARRIER_NR_AVAILABILITY_SA) == nrModeSupportedList_[slotId].end()) {
556         return false;
557     }
558     return isGbaValid;
559 }
560 
IsVonrSupportedForImsSwitch(int32_t slotId,bool isGbaValid)561 bool CellularCallConfig::IsVonrSupportedForImsSwitch(int32_t slotId, bool isGbaValid)
562 {
563     NrMode nrMode = NrMode::NR_MODE_UNKNOWN;
564     int32_t queryRet = CoreManagerInner::GetInstance().GetNrOptionMode(slotId, nrMode);
565     if (queryRet != TELEPHONY_SUCCESS) {
566         TELEPHONY_LOGE("get nr mode value failed");
567         return isGbaValid;
568     }
569     TELEPHONY_LOGI("nr mode value is %{public}d", nrMode);
570     return nrMode == NrMode::NR_MODE_NSA_AND_SA || nrMode == NrMode::NR_MODE_SA_ONLY;
571 }
572 
IsUtProvisioned(int32_t slotId)573 bool CellularCallConfig::IsUtProvisioned(int32_t slotId)
574 {
575     if (utProvisioningSupported_[slotId]) {
576         int32_t utFeatureValue;
577         int32_t result = configRequest_.GetImsFeatureValueRequest(FeatureType::TYPE_SS_OVER_UT, utFeatureValue);
578         if (result != TELEPHONY_SUCCESS) {
579             TELEPHONY_LOGE("get ut feature value failed");
580             return false;
581         }
582         return utFeatureValue == ImsFeatureIntResult::IMS_FEATURE_INT_VALUE_ENABLED;
583     }
584     return true;
585 }
586 
BuildEmergencyCall(int32_t slotId,const EmergencyInfo & from)587 EmergencyCall CellularCallConfig::BuildEmergencyCall(int32_t slotId, const EmergencyInfo &from)
588 {
589     EmergencyCall to = {};
590     to.eccNum = from.eccNum;
591     to.eccType = EccType(from.category);
592     to.simpresent = SimpresentType(from.simpresent);
593     to.mcc = from.mcc;
594     to.abnormalService = AbnormalServiceType(from.abnormalService);
595     return to;
596 }
597 
IsNeedTurnOnIms(const ImsCapabilityList & imsCapabilityList)598 bool CellularCallConfig::IsNeedTurnOnIms(const ImsCapabilityList &imsCapabilityList)
599 {
600     for (auto imsCapabilitie : imsCapabilityList.imsCapabilities) {
601         if (imsCapabilitie.imsCapabilityType == ImsCapabilityType::CAPABILITY_TYPE_VOICE
602             || imsCapabilitie.imsCapabilityType == ImsCapabilityType::CAPABILITY_TYPE_VIDEO) {
603             if (imsCapabilitie.enable) {
604                 return true;
605             }
606         }
607     }
608     return false;
609 }
610 
IsSimChanged(int32_t slotId,std::string iccid)611 bool CellularCallConfig::IsSimChanged(int32_t slotId, std::string iccid)
612 {
613     const int32_t sysparaSize = SYSTEM_PARAMETER_LENGTH;
614     char lastIccid[sysparaSize] = { 0 };
615     std::string key = LAST_ICCID_KEY + std::to_string(slotId);
616     GetParameter(key.c_str(), "", lastIccid, sysparaSize);
617 
618     if (iccid.compare(lastIccid) != 0) {
619         SetParameter(key.c_str(), iccid.c_str());
620         return true;
621     }
622     return false;
623 }
624 
SaveImsSwitch(int32_t slotId,int32_t imsSwitchValue)625 int32_t CellularCallConfig::SaveImsSwitch(int32_t slotId, int32_t imsSwitchValue)
626 {
627     int32_t lastImsSwitchValue = IMS_SWITCH_STATUS_UNKNOWN;
628     int32_t queryRet = CoreManagerInner::GetInstance().QueryImsSwitch(slotId, lastImsSwitchValue);
629     if (queryRet != TELEPHONY_SUCCESS) {
630         TELEPHONY_LOGE("query ims switch failed");
631         return SAVE_IMS_SWITCH_FAILED;
632     }
633     if (imsSwitchValue == lastImsSwitchValue) {
634         TELEPHONY_LOGI("ims switch status do not change, imsSwitchValue: %{public}d", imsSwitchValue);
635         return SAVE_IMS_SWITCH_SUCCESS_NOT_CHANGED;
636     }
637     int32_t saveRet = CoreManagerInner::GetInstance().SaveImsSwitch(slotId, imsSwitchValue);
638     if (saveRet != TELEPHONY_SUCCESS) {
639         TELEPHONY_LOGE("save ims switch status to database failed!");
640         return SAVE_IMS_SWITCH_FAILED;
641     }
642     saveImsSwitchStatusToLocal(slotId, imsSwitchValue);
643     SaveVoNRState(slotId, imsSwitchValue);
644     return SAVE_IMS_SWITCH_SUCCESS_CHANGED;
645 }
646 
saveImsSwitchStatusToLocalForPowerOn(int32_t slotId)647 void CellularCallConfig::saveImsSwitchStatusToLocalForPowerOn(int32_t slotId)
648 {
649     int32_t imsSwitchStatus = IMS_SWITCH_STATUS_UNKNOWN;
650     int32_t ret = CoreManagerInner::GetInstance().QueryImsSwitch(slotId, imsSwitchStatus);
651     if (ret != TELEPHONY_SUCCESS || imsSwitchStatus == IMS_SWITCH_STATUS_UNKNOWN) {
652         TELEPHONY_LOGI("get ims switch state failed from database, return operator config default value");
653         imsSwitchStatus = imsSwitchOnByDefault_[slotId] ? IMS_SWITCH_STATUS_ON : IMS_SWITCH_STATUS_OFF;
654     }
655 
656     TELEPHONY_LOGI(
657         "save slotId[%{public}d] imsSwitchStatus:%{public}d to local for Power on", slotId, imsSwitchStatus);
658     std::string imsSwitchStateKey = IMSSWITCH_STATE + std::to_string(slotId);
659     std::string imsSwitchState = std::to_string(imsSwitchStatus);
660     SetParameter(imsSwitchStateKey.c_str(), imsSwitchState.c_str());
661 }
662 
saveImsSwitchStatusToLocal(int32_t slotId,int32_t imsSwitchStatus)663 void CellularCallConfig::saveImsSwitchStatusToLocal(int32_t slotId, int32_t imsSwitchStatus)
664 {
665     TELEPHONY_LOGI("save slotId[%{public}d] imsSwitchStatus:%{public}d to local", slotId, imsSwitchStatus);
666     std::string imsSwitchStateKey = IMSSWITCH_STATE + std::to_string(slotId);
667     std::string imsSwitchState = std::to_string(imsSwitchStatus);
668     SetParameter(imsSwitchStateKey.c_str(), imsSwitchState.c_str());
669 }
670 
SaveVoNRState(int32_t slotId,int32_t state)671 void CellularCallConfig::SaveVoNRState(int32_t slotId, int32_t state)
672 {
673     CellularCallHiSysEvent::WriteVoNRSwitchChangeEvent(state);
674     TELEPHONY_LOGI("slotId: %{public}d, switchState: %{public}d", slotId, state);
675     std::string vonrState = std::to_string(state);
676     std::string vonrStateKey = VONR_STATE + std::to_string(slotId);
677     SetParameter(vonrStateKey.c_str(), vonrState.c_str());
678 }
679 
ObtainVoNRState(int32_t slotId)680 int32_t CellularCallConfig::ObtainVoNRState(int32_t slotId)
681 {
682     std::string vonrStateKey = VONR_STATE + std::to_string(slotId);
683     int32_t vonrState = GetIntParameter(vonrStateKey.c_str(), VONR_SWITCH_STATUS_ON);
684     TELEPHONY_LOGI("slotId: %{public}d, switchState: %{public}d", slotId, vonrState);
685     return vonrState;
686 }
687 
HandleSetLteImsSwitchResult(int32_t slotId,ErrType result)688 void CellularCallConfig::HandleSetLteImsSwitchResult(int32_t slotId, ErrType result)
689 {
690     TELEPHONY_LOGI("CellularCallConfig::HandleSetLteImsSwitchResult entry, slotId: %{public}d", slotId);
691     if (result != ErrType::NONE) {
692         TELEPHONY_LOGE("HandleSetLteImsSwitchResult set ims switch to modem failed!");
693         // need to reset the Ims Switch parameter and notify APP to update UI.
694     }
695 }
696 
HandleSetVoNRSwitchResult(int32_t slotId,ErrType result)697 void CellularCallConfig::HandleSetVoNRSwitchResult(int32_t slotId, ErrType result)
698 {
699     TELEPHONY_LOGD("CellularCallConfig::HandleSetVoNRSwitchResult entry, slotId: %{public}d", slotId);
700     if (result != ErrType::NONE) {
701         TELEPHONY_LOGE("HandleSetVoNRSwitchResult set vonr switch to modem failed!");
702         return;
703     }
704     SaveVoNRState(slotId, vonrSwithStatus_[slotId]);
705     ImsCapabilityList imsCapabilityList;
706     UpdateImsVoiceCapabilities(slotId, imsCapabilityList);
707     configRequest_.UpdateImsCapabilities(slotId, imsCapabilityList);
708 }
709 
GetDomainPreferenceModeResponse(int32_t slotId,int32_t mode)710 void CellularCallConfig::GetDomainPreferenceModeResponse(int32_t slotId, int32_t mode)
711 {
712     modeMap_[slotId] = mode;
713 }
714 
GetImsSwitchStatusResponse(int32_t slotId,int32_t active)715 void CellularCallConfig::GetImsSwitchStatusResponse(int32_t slotId, int32_t active) {}
716 
GetPreferenceMode(int32_t slotId) const717 int32_t CellularCallConfig::GetPreferenceMode(int32_t slotId) const
718 {
719     return modeMap_[slotId];
720 }
721 
GetSwitchStatus(int32_t slotId)722 int32_t CellularCallConfig::GetSwitchStatus(int32_t slotId)
723 {
724     std::string imsSwitchStateKey = IMSSWITCH_STATE + std::to_string(slotId);
725     int32_t imsSwitchStatus = GetIntParameter(imsSwitchStateKey.c_str(), IMS_SWITCH_STATUS_UNKNOWN);
726     if (imsSwitchStatus == IMS_SWITCH_STATUS_UNKNOWN) {
727         TELEPHONY_LOGI("get ims switch state failed from local, try to get it from database");
728         int32_t ret = CoreManagerInner::GetInstance().QueryImsSwitch(slotId, imsSwitchStatus);
729         if (ret != TELEPHONY_SUCCESS || imsSwitchStatus == IMS_SWITCH_STATUS_UNKNOWN) {
730             TELEPHONY_LOGI("get ims switch state failed from database, return operator config default value");
731             imsSwitchStatus = imsSwitchOnByDefault_[slotId] ? IMS_SWITCH_STATUS_ON : IMS_SWITCH_STATUS_OFF;
732         }
733     }
734     TELEPHONY_LOGD("slotId[%{public}d] GetSwitchStatus imsSwitchStatus:%{public}d", slotId, imsSwitchStatus);
735     return imsSwitchStatus;
736 }
737 
SetImsConfig(ImsConfigItem item,const std::string & value)738 int32_t CellularCallConfig::SetImsConfig(ImsConfigItem item, const std::string &value)
739 {
740     return configRequest_.SetImsConfigRequest(item, value);
741 }
742 
SetImsConfig(ImsConfigItem item,int32_t value)743 int32_t CellularCallConfig::SetImsConfig(ImsConfigItem item, int32_t value)
744 {
745     return configRequest_.SetImsConfigRequest(item, value);
746 }
747 
GetImsConfig(ImsConfigItem item)748 int32_t CellularCallConfig::GetImsConfig(ImsConfigItem item)
749 {
750     return configRequest_.GetImsConfigRequest(item);
751 }
752 
SetImsFeatureValue(FeatureType type,int32_t value)753 int32_t CellularCallConfig::SetImsFeatureValue(FeatureType type, int32_t value)
754 {
755     return configRequest_.SetImsFeatureValueRequest(type, value);
756 }
757 
GetImsFeatureValue(FeatureType type)758 int32_t CellularCallConfig::GetImsFeatureValue(FeatureType type)
759 {
760     int32_t imsFeatureValue;
761     int32_t ret = configRequest_.GetImsFeatureValueRequest(type, imsFeatureValue);
762     GetImsFeatureValueResponse response;
763     response.result = ret;
764     response.value = imsFeatureValue;
765     DelayedSingleton<CellularCallRegister>::GetInstance()->ReportGetImsFeatureResult(response);
766     return ret;
767 }
768 
SetTempMode(int32_t slotId)769 void CellularCallConfig::SetTempMode(int32_t slotId)
770 {
771     modeMap_[slotId] = modeTempMap_[slotId];
772 }
773 
InitModeActive()774 void CellularCallConfig::InitModeActive()
775 {
776     TELEPHONY_LOGI("InitModeActive");
777     int32_t slotId = DEFAULT_SIM_SLOT_ID;
778     modeMap_[slotId] = DomainPreferenceMode::IMS_PS_VOICE_PREFERRED;
779     std::unique_lock<std::shared_mutex> lock(mutex_);
780     eccListRadioMap_.clear();
781     eccList3gppHasSim_.clear();
782     eccList3gppNoSim_.clear();
783     allEccList_.clear();
784     eccList3gppHasSim_.push_back(BuildDefaultEmergencyCall("112", SimpresentType::TYPE_HAS_CARD));
785     eccList3gppHasSim_.push_back(BuildDefaultEmergencyCall("911", SimpresentType::TYPE_HAS_CARD));
786     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("112", SimpresentType::TYPE_NO_CARD));
787     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("911", SimpresentType::TYPE_NO_CARD));
788     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("000", SimpresentType::TYPE_NO_CARD));
789     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("08", SimpresentType::TYPE_NO_CARD));
790     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("110", SimpresentType::TYPE_NO_CARD));
791     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("118", SimpresentType::TYPE_NO_CARD));
792     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("119", SimpresentType::TYPE_NO_CARD));
793     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("999", SimpresentType::TYPE_NO_CARD));
794     TELEPHONY_LOGD("InitModeActive finish");
795 }
796 
BuildDefaultEmergencyCall(const std::string & number,SimpresentType simType)797 EmergencyCall CellularCallConfig::BuildDefaultEmergencyCall(const std::string &number, SimpresentType simType)
798 {
799     TELEPHONY_LOGD("BuildDefaultEmergencyCall, eccNum:%{public}s", number.c_str());
800     EmergencyCall emergencyCall;
801     emergencyCall.eccNum = number;
802     emergencyCall.eccType = EccType::TYPE_CATEGORY;
803     emergencyCall.simpresent = simType;
804     emergencyCall.mcc = "";
805     emergencyCall.abnormalService = AbnormalServiceType::TYPE_ALL;
806     std::string::size_type pos = number.find('+');
807     if (pos != std::string::npos) {
808         int32_t startOps = 0;
809         std::string category = number.substr(startOps, pos);
810         emergencyCall.eccType = static_cast<EccType>(std::atoi(category.c_str()));
811         emergencyCall.eccNum = number.substr(pos, number.size());
812     }
813     return emergencyCall;
814 }
815 
GetRoamingState(int32_t slotId)816 bool CellularCallConfig::GetRoamingState(int32_t slotId)
817 {
818     sptr<NetworkState> networkState = nullptr;
819     CoreManagerInner::GetInstance().GetNetworkStatus(slotId, networkState);
820     if (networkState == nullptr) {
821         TELEPHONY_LOGE("networkState get failed, slotId: %{public}d", slotId);
822         return false;
823     }
824     bool isRoaming = networkState->IsRoaming();
825     TELEPHONY_LOGD("isRoaming=%{public}d", isRoaming);
826     return isRoaming;
827 }
828 
MergeEccCallList(int32_t slotId)829 void CellularCallConfig::MergeEccCallList(int32_t slotId)
830 {
831     std::map<int32_t, std::vector<EmergencyCall>> tempEccList;
832     std::string mcc = GetMcc(slotId);
833     for (auto ecc : eccListRadioMap_[slotId]) {
834         ecc.mcc = mcc;
835         tempEccList[slotId].push_back(ecc);
836     }
837     TELEPHONY_LOGD("MergeEccCallList merge radio slotId  %{public}d size  %{public}d", slotId,
838         static_cast<int32_t>(eccListRadioMap_[slotId].size()));
839     SimState simState = SimState::SIM_STATE_UNKNOWN;
840     CoreManagerInner::GetInstance().GetSimState(slotId, simState);
841     bool hasSim = simState == SimState::SIM_STATE_READY || simState == SimState::SIM_STATE_LOADED;
842     if (hasSim) {
843         if (!mcc.empty()) {
844             for (auto ecc : eccList3gppHasSim_) {
845                 ecc.mcc = mcc;
846                 tempEccList[slotId].push_back(ecc);
847             }
848         }
849     } else {
850         for (auto ecc : eccList3gppNoSim_) {
851             ecc.mcc = mcc;
852             tempEccList[slotId].push_back(ecc);
853         }
854     }
855     std::u16string u16Hplmn = u"";
856     CoreManagerInner::GetInstance().GetSimOperatorNumeric(slotId, u16Hplmn);
857     std::string hplmn = Str16ToStr8(u16Hplmn);
858     if (hasSim && !GetRoamingState(slotId) && !hplmn.empty()) {
859         std::vector<EccNum> eccVec;
860         DelayedSingleton<CellularCallRdbHelper>::GetInstance()->QueryEccList(hplmn, eccVec);
861         if (!eccVec.empty()) {
862             std::string ecc = eccVec[0].ecc_fake;
863             std::vector<std::string> callList = StandardizeUtils::Split(ecc, ",");
864             for (auto it : callList) {
865                 EmergencyCall call = BuildDefaultEmergencyCall(it, SimpresentType::TYPE_HAS_CARD);
866                 call.mcc = mcc;
867                 tempEccList[slotId].push_back(call);
868             }
869         }
870     }
871     UniqueEccCallList(slotId, tempEccList[slotId]);
872 }
873 
UniqueEccCallList(int32_t slotId,std::vector<EmergencyCall> & eccList)874 void CellularCallConfig::UniqueEccCallList(int32_t slotId, std::vector<EmergencyCall> &eccList)
875 {
876     allEccList_[slotId].clear();
877     for (auto call : eccList) {
878         if (std::find(allEccList_[slotId].begin(), allEccList_[slotId].end(), call) ==
879             allEccList_[slotId].end()) {
880             allEccList_[slotId].push_back(call);
881         }
882     }
883     for (auto call : allEccList_[slotId]) {
884         TELEPHONY_LOGD("UniqueEccCallList end slotId %{public}d eccNum:%{public}s, mcc:%{public}s", slotId,
885             call.eccNum.c_str(), call.mcc.c_str());
886     }
887 }
888 
GetMcc(int32_t slotId)889 std::string CellularCallConfig::GetMcc(int32_t slotId)
890 {
891     std::u16string operatorNumeric;
892     CoreManagerInner::GetInstance().GetSimOperatorNumeric(slotId, operatorNumeric);
893     std::string imsi = Str16ToStr8(operatorNumeric);
894     int len = static_cast<int>(imsi.length());
895     std::string mcc = imsi;
896     if (len >= MCC_LEN) {
897         mcc = imsi.substr(0, MCC_LEN);
898     }
899     TELEPHONY_LOGD("getMcc slotd %{public}d mcc %{public}s end", slotId, mcc.c_str());
900     return mcc;
901 }
902 
SetMute(int32_t slotId,int32_t mute)903 int32_t CellularCallConfig::SetMute(int32_t slotId, int32_t mute)
904 {
905     return configRequest_.SetMuteRequest(slotId, mute);
906 }
907 
GetMute(int32_t slotId)908 int32_t CellularCallConfig::GetMute(int32_t slotId)
909 {
910     return configRequest_.GetMuteRequest(slotId);
911 }
912 
GetEmergencyCallList(int32_t slotId)913 int32_t CellularCallConfig::GetEmergencyCallList(int32_t slotId)
914 {
915     return configRequest_.GetEmergencyCallListRequest(slotId);
916 }
917 
SetEmergencyCallList(int32_t slotId,std::vector<EmergencyCall> & eccVec)918 int32_t CellularCallConfig::SetEmergencyCallList(int32_t slotId, std::vector<EmergencyCall> &eccVec)
919 {
920     TELEPHONY_LOGD("SetEmergencyCallList start %{public}d", slotId);
921     return configRequest_.SetEmergencyCallListRequest(slotId, eccVec);
922 }
923 
CheckAndUpdateSimState(int32_t slotId)924 bool CellularCallConfig::CheckAndUpdateSimState(int32_t slotId)
925 {
926     SimState simState = SimState::SIM_STATE_UNKNOWN;
927     CoreManagerInner::GetInstance().GetSimState(slotId, simState);
928     int32_t simStateForEcc;
929     switch (simState) {
930         case SimState::SIM_STATE_READY:
931         case SimState::SIM_STATE_LOADED: {
932             simStateForEcc = SIM_PRESENT;
933             break;
934         }
935         default: {
936             simStateForEcc = SIM_ABSENT;
937             break;
938         }
939     }
940     std::unique_lock<std::shared_mutex> lock(simStateLock_);
941     bool result = (simState_[slotId] != simStateForEcc);
942     simState_[slotId] = simStateForEcc;
943     return result;
944 }
945 
UpdateEmergencyCallFromRadio(int32_t slotId,const EmergencyInfoList & eccList)946 void CellularCallConfig::UpdateEmergencyCallFromRadio(int32_t slotId, const EmergencyInfoList &eccList)
947 {
948     TELEPHONY_LOGD("UpdateEmergencyCallFromRadio %{public}d size %{public}d", slotId, eccList.callSize);
949     std::unique_lock<std::shared_mutex> lock(mutex_);
950     eccListRadioMap_[slotId].clear();
951     for (auto ecc : eccList.calls) {
952         TELEPHONY_LOGD("UpdateEmergencyCallFromRadio , data: eccNum %{public}s mcc %{public}s", ecc.eccNum.c_str(),
953             ecc.mcc.c_str());
954         eccListRadioMap_[slotId].push_back(BuildEmergencyCall(slotId, ecc));
955     }
956     MergeEccCallList(slotId);
957 }
958 
GetEccCallList(int32_t slotId)959 std::vector<EmergencyCall> CellularCallConfig::GetEccCallList(int32_t slotId)
960 {
961     TELEPHONY_LOGD("GetEccCallList  start %{public}d", slotId);
962     std::shared_lock<std::shared_mutex> lock(mutex_);
963     TELEPHONY_LOGD("GetEccCallList size %{public}zu", allEccList_[slotId].size());
964     for (auto ecc : allEccList_[slotId]) {
965         TELEPHONY_LOGD("GetEccCallList, data: eccNum %{public}s mcc %{public}s", ecc.eccNum.c_str(), ecc.mcc.c_str());
966     }
967     return allEccList_[slotId];
968 }
969 
BooleanToImsSwitchValue(bool value)970 int32_t CellularCallConfig::BooleanToImsSwitchValue(bool value)
971 {
972     return value ? IMS_SWITCH_STATUS_ON : IMS_SWITCH_STATUS_OFF;
973 }
974 
GetImsSwitchOnByDefaultConfig(int32_t slotId)975 bool CellularCallConfig::GetImsSwitchOnByDefaultConfig(int32_t slotId)
976 {
977     if (!IsValidSlotId(slotId)) {
978         TELEPHONY_LOGE("invalid slot id");
979         return true;
980     }
981     return imsSwitchOnByDefault_[slotId];
982 }
983 
GethideImsSwitchConfig(int32_t slotId)984 bool CellularCallConfig::GethideImsSwitchConfig(int32_t slotId)
985 {
986     if (!IsValidSlotId(slotId)) {
987         TELEPHONY_LOGE("invalid slot id");
988         return false;
989     }
990     return hideImsSwitch_[slotId];
991 }
992 
GetvolteSupportedConfig(int32_t slotId)993 bool CellularCallConfig::GetvolteSupportedConfig(int32_t slotId)
994 {
995     if (!IsValidSlotId(slotId)) {
996         TELEPHONY_LOGE("invalid slot id");
997         return false;
998     }
999     return volteSupported_[slotId];
1000 }
1001 
GetNrModeSupportedListConfig(int32_t slotId)1002 std::vector<int32_t> CellularCallConfig::GetNrModeSupportedListConfig(int32_t slotId)
1003 {
1004     if (!IsValidSlotId(slotId)) {
1005         TELEPHONY_LOGE("invalid slot id");
1006         return std::vector<int32_t> { CARRIER_NR_AVAILABILITY_NSA, CARRIER_NR_AVAILABILITY_SA };
1007     }
1008     return nrModeSupportedList_[slotId];
1009 }
1010 
GetVolteProvisioningSupportedConfig(int32_t slotId)1011 bool CellularCallConfig::GetVolteProvisioningSupportedConfig(int32_t slotId)
1012 {
1013     if (!IsValidSlotId(slotId)) {
1014         TELEPHONY_LOGE("invalid slot id");
1015         return false;
1016     }
1017     return volteProvisioningSupported_[slotId];
1018 }
1019 
GetSsOverUtSupportedConfig(int32_t slotId)1020 bool CellularCallConfig::GetSsOverUtSupportedConfig(int32_t slotId)
1021 {
1022     if (!IsValidSlotId(slotId)) {
1023         TELEPHONY_LOGE("invalid slot id");
1024         return false;
1025     }
1026     return ssOverUtSupported_[slotId];
1027 }
1028 
GetImsGbaRequiredConfig(int32_t slotId)1029 bool CellularCallConfig::GetImsGbaRequiredConfig(int32_t slotId)
1030 {
1031     if (!IsValidSlotId(slotId)) {
1032         TELEPHONY_LOGE("invalid slot id");
1033         return false;
1034     }
1035     return imsGbaRequired_[slotId];
1036 }
1037 
GetUtProvisioningSupportedConfig(int32_t slotId)1038 bool CellularCallConfig::GetUtProvisioningSupportedConfig(int32_t slotId)
1039 {
1040     if (!IsValidSlotId(slotId)) {
1041         TELEPHONY_LOGE("invalid slot id");
1042         return false;
1043     }
1044     return utProvisioningSupported_[slotId];
1045 }
1046 
GetImsPreferForEmergencyConfig(int32_t slotId)1047 bool CellularCallConfig::GetImsPreferForEmergencyConfig(int32_t slotId)
1048 {
1049     if (!IsValidSlotId(slotId)) {
1050         TELEPHONY_LOGE("invalid slot id");
1051         return true;
1052     }
1053     return imsPreferForEmergency_[slotId];
1054 }
1055 
GetCallWaitingServiceClassConfig(int32_t slotId)1056 std::int32_t CellularCallConfig::GetCallWaitingServiceClassConfig(int32_t slotId)
1057 {
1058     if (!IsValidSlotId(slotId)) {
1059         TELEPHONY_LOGE("invalid slot id");
1060         return 1;
1061     }
1062     return callWaitingServiceClass_[slotId];
1063 }
1064 
GetImsCallDisconnectResoninfoMappingConfig(int32_t slotId)1065 std::vector<std::string> CellularCallConfig::GetImsCallDisconnectResoninfoMappingConfig(int32_t slotId)
1066 {
1067     std::lock_guard<std::mutex> lock(operatorMutex_);
1068     if (!IsValidSlotId(slotId)) {
1069         TELEPHONY_LOGE("invalid slot id");
1070         return std::vector<std::string> {};
1071     }
1072     return imsCallDisconnectResoninfoMapping_[slotId];
1073 }
1074 
GetForceVolteSwitchOnConfig(int32_t slotId)1075 bool CellularCallConfig::GetForceVolteSwitchOnConfig(int32_t slotId)
1076 {
1077     if (!IsValidSlotId(slotId)) {
1078         TELEPHONY_LOGE("invalid slot id");
1079         return false;
1080     }
1081     return forceVolteSwitchOn_[slotId];
1082 }
1083 
IsValidSlotId(int32_t slotId)1084 bool CellularCallConfig::IsValidSlotId(int32_t slotId)
1085 {
1086     int32_t count = SIM_SLOT_COUNT;
1087     if ((slotId >= DEFAULT_SIM_SLOT_ID) && (slotId < count)) {
1088         return true;
1089     }
1090 
1091     TELEPHONY_LOGE("SlotId is InValid = %{public}d", slotId);
1092     return false;
1093 }
1094 
SetReadyToCall(int32_t slotId,bool isReadyToCall)1095 void CellularCallConfig::SetReadyToCall(int32_t slotId, bool isReadyToCall)
1096 {
1097     if (!IsValidSlotId(slotId)) {
1098         TELEPHONY_LOGE("invalid slot id");
1099         return;
1100     }
1101     readyToCall_[slotId] = isReadyToCall;
1102 }
1103 
IsReadyToCall(int32_t slotId)1104 bool CellularCallConfig::IsReadyToCall(int32_t slotId)
1105 {
1106     if (!IsValidSlotId(slotId)) {
1107         TELEPHONY_LOGE("invalid slot id");
1108         return false;
1109     }
1110     return readyToCall_[slotId];
1111 }
1112 
NeedReadThirdParyLib()1113 bool CellularCallConfig::NeedReadThirdParyLib()
1114 {
1115     std::string readThirdParty = system::GetParameter(KEY_CONST_TELEPHONY_READ_THIRD_PARTY_LIB, "");
1116     if (readThirdParty.compare("false") == 0) {
1117         return false;
1118     }
1119     return true;
1120 }
1121 
GetVideoCallWaiting(int32_t slotId,bool & enabled)1122 int32_t CellularCallConfig::GetVideoCallWaiting(int32_t slotId, bool &enabled)
1123 {
1124     TELEPHONY_LOGE("entry, slotId: %{public}d", slotId);
1125     auto it = videoCallWaiting_.find(slotId);
1126     if (it != videoCallWaiting_.end()) {
1127         enabled = it->second;
1128     } else {
1129         TELEPHONY_LOGI("videoCallWaiting_ not find slotId:%{public}d", slotId);
1130         enabled = false;
1131     }
1132     return TELEPHONY_SUCCESS;
1133 }
1134 
GetImsSwitchStatusRequest(int32_t slotId)1135 void CellularCallConfig::GetImsSwitchStatusRequest(int32_t slotId)
1136 {
1137     configRequest_.GetImsSwitchStatusRequest(slotId);
1138 }
1139 
IsVolteSupport(int32_t slotId)1140 bool CellularCallConfig::IsVolteSupport(int32_t slotId)
1141 {
1142     if (!IsValidSlotId(slotId)) {
1143         TELEPHONY_LOGE("inValid slot id %{public}d", slotId);
1144         return false;
1145     }
1146     bool imsSwitch = false;
1147     GetImsSwitchStatus(slotId, imsSwitch);
1148     bool isGbaValid = IsGbaValid(slotId);
1149     bool isVolteProvisioned = IsVolteProvisioned(slotId);
1150     TELEPHONY_LOGI("Slot[%{public}d] voltesupport[%{public}d], isGbaValid[%{public}d], imsSwitch[%{public}d], "
1151         "isVolteProvisioned[%{public}d]", slotId, volteSupported_[slotId], isGbaValid, imsSwitch, isVolteProvisioned);
1152     return volteSupported_[slotId] && isGbaValid && imsSwitch && isVolteProvisioned;
1153 }
1154 } // namespace Telephony
1155 } // namespace OHOS
1156