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