• 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     if (isHomeNetRegister && simState_[slotId] == SIM_PRESENT) {
294         OperatorConfig operatorConfig;
295         CoreManagerInner::GetInstance().GetOperatorConfigs(slotId, operatorConfig);
296         callListWithCard = operatorConfig.stringArrayValue[KEY_EMERGENCY_CALL_STRING_ARRAY];
297         if (callListWithCard.empty()) {
298             DelayedSingleton<CellularCallRdbHelper>::GetInstance()->QueryEccList(hplmn, eccVec);
299             GetEccListFromResult(eccVec, callListWithCard, callListNoCard);
300         }
301     } else {
302         if (curPlmn_[slotId].empty()) {
303             std::u16string u16Rplmn = CoreManagerInner::GetInstance().GetOperatorNumeric(slotId);
304             std::string rplmn = Str16ToStr8(u16Rplmn);
305             if (rplmn.empty()) {
306                 TELEPHONY_LOGE("rplmn is empty");
307                 return;
308             }
309             curPlmn_[slotId] = rplmn;
310         }
311         DelayedSingleton<CellularCallRdbHelper>::GetInstance()->QueryEccList(curPlmn_[slotId], eccVec);
312         GetEccListFromResult(eccVec, callListWithCard, callListNoCard);
313     }
314     std::vector<EmergencyCall> eccInfoList;
315     for (auto it : callListWithCard) {
316         eccInfoList.push_back(BuildDefaultEmergencyCall(it, SimpresentType::TYPE_HAS_CARD));
317     }
318     for (auto it : callListNoCard) {
319         eccInfoList.push_back(BuildDefaultEmergencyCall(it, SimpresentType::TYPE_NO_CARD));
320     }
321     SetEmergencyCallList(slotId, eccInfoList);
322 }
323 
HandleSimAccountLoaded(int32_t slotId)324 void CellularCallConfig::HandleSimAccountLoaded(int32_t slotId)
325 {
326     TELEPHONY_LOGI("entry, slotId: %{public}d", slotId);
327     saveImsSwitchStatusToLocalForPowerOn(slotId);
328     ResetImsSwitch(slotId);
329     UpdateImsCapabilities(slotId, true);
330     CheckAndUpdateSimState(slotId);
331     UpdateEccNumberList(slotId);
332 }
333 
HandleOperatorConfigChanged(int32_t slotId)334 void CellularCallConfig::HandleOperatorConfigChanged(int32_t slotId)
335 {
336     OperatorConfig operatorConfig;
337     int32_t ret = CoreManagerInner::GetInstance().GetOperatorConfigs(slotId, operatorConfig);
338     if (ret != TELEPHONY_SUCCESS) {
339         TELEPHONY_LOGE("failed due to get operator config");
340         return;
341     }
342 
343     int32_t result = ParseAndCacheOperatorConfigs(slotId, operatorConfig);
344     if (result != TELEPHONY_SUCCESS) {
345         TELEPHONY_LOGE("failed due to parse operator config");
346         return;
347     }
348     ResetImsSwitch(slotId);
349     UpdateImsCapabilities(slotId, true);
350 }
351 
ParseAndCacheOperatorConfigs(int32_t slotId,OperatorConfig & poc)352 int32_t CellularCallConfig::ParseAndCacheOperatorConfigs(int32_t slotId, OperatorConfig &poc)
353 {
354     TELEPHONY_LOGI("CellularCallConfig::ParseAndCacheOperatorConfigs start. slotId %{public}d", slotId);
355     std::lock_guard<std::mutex> lock(operatorMutex_);
356     if (!IsValidSlotId(slotId)) {
357         TELEPHONY_LOGE(" invalid slot id %{public}d", slotId);
358         return TELEPHONY_ERROR;
359     }
360 
361     ParseBoolOperatorConfigs(slotId, imsSwitchOnByDefault_, poc, KEY_IMS_SWITCH_ON_BY_DEFAULT_BOOL);
362     ParseBoolOperatorConfigs(slotId, hideImsSwitch_, poc, KEY_HIDE_IMS_SWITCH_BOOL);
363     ParseBoolOperatorConfigs(slotId, volteSupported_, poc, KEY_VOLTE_SUPPORTED_BOOL);
364     ParseBoolOperatorConfigs(slotId, volteProvisioningSupported_, poc, KEY_VOLTE_PROVISIONING_SUPPORTED_BOOL);
365     ParseBoolOperatorConfigs(slotId, ssOverUtSupported_, poc, KEY_SS_OVER_UT_SUPPORTED_BOOL);
366     ParseBoolOperatorConfigs(slotId, imsGbaRequired_, poc, KEY_IMS_GBA_REQUIRED_BOOL);
367     ParseBoolOperatorConfigs(slotId, utProvisioningSupported_, poc, KEY_UT_PROVISIONING_SUPPORTED_BOOL);
368     ParseBoolOperatorConfigs(slotId, imsPreferForEmergency_, poc, KEY_IMS_PREFER_FOR_EMERGENCY_BOOL);
369     ParseBoolOperatorConfigs(slotId, forceVolteSwitchOn_, poc, KEY_FORCE_VOLTE_SWITCH_ON_BOOL);
370 
371     if (poc.intArrayValue.count(KEY_NR_MODE_SUPPORTED_LIST_INT_ARRAY) > 0) {
372         nrModeSupportedList_[slotId] = poc.intArrayValue[KEY_NR_MODE_SUPPORTED_LIST_INT_ARRAY];
373     }
374     if (poc.intValue.count(KEY_CALL_WAITING_SERVICE_CLASS_INT) > 0) {
375         callWaitingServiceClass_[slotId] = poc.intValue[KEY_CALL_WAITING_SERVICE_CLASS_INT];
376     }
377     if (poc.stringArrayValue.count(KEY_IMS_CALL_DISCONNECT_REASONINFO_MAPPING_STRING_ARRAY) > 0) {
378         imsCallDisconnectResoninfoMapping_[slotId] =
379             poc.stringArrayValue[KEY_IMS_CALL_DISCONNECT_REASONINFO_MAPPING_STRING_ARRAY];
380     }
381     return TELEPHONY_SUCCESS;
382 }
383 
ParseBoolOperatorConfigs(int32_t slotId,std::map<int32_t,bool> & config,OperatorConfig & poc,std::string configName)384 void CellularCallConfig::ParseBoolOperatorConfigs(
385     int32_t slotId, std::map<int32_t, bool> &config, OperatorConfig &poc, std::string configName)
386 {
387     auto it = poc.boolValue.find(configName);
388     if (it != poc.boolValue.end()) {
389         config[slotId] = it->second;
390     } else {
391         TELEPHONY_LOGE("do't find operator config %{public}s", configName.c_str());
392     }
393 }
394 
ResetImsSwitch(int32_t slotId)395 void CellularCallConfig::ResetImsSwitch(int32_t slotId)
396 {
397     bool hasSimCard = false;
398     CoreManagerInner::GetInstance().HasSimCard(slotId, hasSimCard);
399     if (!hasSimCard) {
400         TELEPHONY_LOGE("return due to no sim card");
401         return;
402     }
403     std::u16string iccId;
404     CoreManagerInner::GetInstance().GetSimIccId(slotId, iccId);
405     if (IsSimChanged(slotId, Str16ToStr8(iccId)) && forceVolteSwitchOn_[slotId]) {
406         int32_t ret = CoreManagerInner::GetInstance().SaveImsSwitch(
407             slotId, BooleanToImsSwitchValue(imsSwitchOnByDefault_[slotId]));
408         if (ret != TELEPHONY_SUCCESS) {
409             TELEPHONY_LOGE("SaveImsSwitch failed");
410         } else {
411             saveImsSwitchStatusToLocal(slotId, BooleanToImsSwitchValue(imsSwitchOnByDefault_[slotId]));
412         }
413     }
414 }
415 
UpdateImsCapabilities(int32_t slotId,bool needUpdateUtCapability)416 void CellularCallConfig::UpdateImsCapabilities(int32_t slotId, bool needUpdateUtCapability)
417 {
418     bool isGbaValid = IsGbaValid(slotId);
419     ImsCapabilityList imsCapabilityList;
420     TELEPHONY_LOGI("UpdateImsCapabilities entry");
421     UpdateImsVoiceCapabilities(slotId, isGbaValid, imsCapabilityList);
422     if (needUpdateUtCapability) {
423         UpdateImsUtCapabilities(slotId, isGbaValid, imsCapabilityList);
424     }
425     configRequest_.UpdateImsCapabilities(slotId, imsCapabilityList);
426     configRequest_.SetImsSwitchStatusRequest(slotId, IsNeedTurnOnIms(imsCapabilityList));
427 }
IsGbaValid(int32_t slotId)428 bool CellularCallConfig::IsGbaValid(int32_t slotId)
429 {
430     if (imsGbaRequired_[slotId]) {
431         std::u16string simist = CoreManagerInner::GetInstance().GetSimIst(slotId);
432         std::string simistStr = Str16ToStr8(simist);
433         // If carrier requires that IMS is only available if GBA capable SIM is used,
434         // then this function checks GBA bit in EF IST.
435         // Format of EF IST is defined in 3GPP TS 31.103 (Section 4.2.7).
436         if (!simistStr.empty() && simistStr.length() > 1) {
437             bool result = (IMS_GBA_BIT & simistStr.at(1)) != 0;
438             return result;
439         }
440     }
441     return true;
442 }
443 
UpdateImsVoiceCapabilities(int32_t slotId,bool isGbaValid,ImsCapabilityList & imsCapabilityList)444 void CellularCallConfig::UpdateImsVoiceCapabilities(
445     int32_t slotId, bool isGbaValid, ImsCapabilityList &imsCapabilityList)
446 {
447     bool imsSwitch = false;
448     GetImsSwitchStatus(slotId, imsSwitch);
449     ImsCapability volteCapability;
450     volteCapability.imsCapabilityType = ImsCapabilityType::CAPABILITY_TYPE_VOICE;
451     volteCapability.imsRadioTech = ImsRegTech::IMS_REG_TECH_LTE;
452     volteCapability.enable = volteSupported_[slotId] && isGbaValid && imsSwitch && IsVolteProvisioned(slotId);
453     imsCapabilityList.imsCapabilities.push_back(volteCapability);
454 
455     int32_t vonrSwitch = VONR_SWITCH_STATUS_OFF;
456     GetVoNRSwitchStatus(slotId, vonrSwitch);
457     bool vonrSwitchEnabled = vonrSwitch == VONR_SWITCH_STATUS_ON;
458     ImsCapability vonrCapability;
459     vonrCapability.imsCapabilityType = ImsCapabilityType::CAPABILITY_TYPE_VOICE;
460     vonrCapability.imsRadioTech = ImsRegTech::IMS_REG_TECH_NR;
461     vonrCapability.enable = volteCapability.enable && IsVonrSupported(slotId, isGbaValid) && vonrSwitchEnabled;
462     imsCapabilityList.imsCapabilities.push_back(vonrCapability);
463 }
464 
UpdateImsUtCapabilities(int32_t slotId,bool isGbaValid,ImsCapabilityList & imsCapabilityList)465 void CellularCallConfig::UpdateImsUtCapabilities(int32_t slotId, bool isGbaValid, ImsCapabilityList &imsCapabilityList)
466 {
467     ImsCapability utCapability;
468     utCapability.imsCapabilityType = ImsCapabilityType::CAPABILITY_TYPE_UT;
469     utCapability.imsRadioTech = ImsRegTech::IMS_REG_TECH_LTE;
470     utCapability.enable = ssOverUtSupported_[slotId] && isGbaValid && IsUtProvisioned(slotId);
471     imsCapabilityList.imsCapabilities.push_back(utCapability);
472 }
473 
IsVolteProvisioned(int32_t slotId)474 bool CellularCallConfig::IsVolteProvisioned(int32_t slotId)
475 {
476     if (volteProvisioningSupported_[slotId]) {
477         int32_t volteFeatureValue;
478         int32_t result = configRequest_.GetImsFeatureValueRequest(FeatureType::TYPE_VOICE_OVER_LTE, volteFeatureValue);
479         if (result != TELEPHONY_SUCCESS) {
480             TELEPHONY_LOGE("get volte feature value failed");
481             return false;
482         }
483         return volteFeatureValue == ImsFeatureIntResult::IMS_FEATURE_INT_VALUE_ENABLED;
484     }
485     return true;
486 }
487 
IsVonrSupported(int32_t slotId,bool isGbaValid)488 bool CellularCallConfig::IsVonrSupported(int32_t slotId, bool isGbaValid)
489 {
490     if (std::find(nrModeSupportedList_[slotId].begin(), nrModeSupportedList_[slotId].end(),
491         CARRIER_NR_AVAILABILITY_SA) == nrModeSupportedList_[slotId].end()) {
492         return false;
493     }
494     return isGbaValid;
495 }
496 
IsUtProvisioned(int32_t slotId)497 bool CellularCallConfig::IsUtProvisioned(int32_t slotId)
498 {
499     if (utProvisioningSupported_[slotId]) {
500         int32_t utFeatureValue;
501         int32_t result = configRequest_.GetImsFeatureValueRequest(FeatureType::TYPE_SS_OVER_UT, utFeatureValue);
502         if (result != TELEPHONY_SUCCESS) {
503             TELEPHONY_LOGE("get ut feature value failed");
504             return false;
505         }
506         return utFeatureValue == ImsFeatureIntResult::IMS_FEATURE_INT_VALUE_ENABLED;
507     }
508     return true;
509 }
510 
BuildEmergencyCall(int32_t slotId,const EmergencyInfo & from)511 EmergencyCall CellularCallConfig::BuildEmergencyCall(int32_t slotId, const EmergencyInfo &from)
512 {
513     EmergencyCall to = {};
514     to.eccNum = from.eccNum;
515     to.eccType = EccType(from.category);
516     to.simpresent = SimpresentType(from.simpresent);
517     to.mcc = from.mcc;
518     to.abnormalService = AbnormalServiceType(from.abnormalService);
519     return to;
520 }
521 
IsNeedTurnOnIms(const ImsCapabilityList & imsCapabilityList)522 bool CellularCallConfig::IsNeedTurnOnIms(const ImsCapabilityList &imsCapabilityList)
523 {
524     for (auto imsCapabilitie : imsCapabilityList.imsCapabilities) {
525         if (imsCapabilitie.imsCapabilityType == ImsCapabilityType::CAPABILITY_TYPE_VOICE
526             || imsCapabilitie.imsCapabilityType == ImsCapabilityType::CAPABILITY_TYPE_VIDEO) {
527             if (imsCapabilitie.enable) {
528                 return true;
529             }
530         }
531     }
532     return false;
533 }
534 
IsSimChanged(int32_t slotId,std::string iccid)535 bool CellularCallConfig::IsSimChanged(int32_t slotId, std::string iccid)
536 {
537     const int32_t sysparaSize = SYSTEM_PARAMETER_LENGTH;
538     char lastIccid[sysparaSize] = { 0 };
539     std::string key = LAST_ICCID_KEY + std::to_string(slotId);
540     GetParameter(key.c_str(), "", lastIccid, sysparaSize);
541 
542     if (iccid.compare(lastIccid) != 0) {
543         SetParameter(key.c_str(), iccid.c_str());
544         return true;
545     }
546     return false;
547 }
548 
ChangeImsSwitchWithOperatorConfig(int32_t slotId,bool active)549 bool CellularCallConfig::ChangeImsSwitchWithOperatorConfig(int32_t slotId, bool active)
550 {
551     auto itorHide = hideImsSwitch_.find(slotId);
552     if (itorHide != hideImsSwitch_.end()) {
553         if (itorHide->second) {
554             auto itorSwitch = imsSwitchOnByDefault_.find(slotId);
555             if (itorSwitch != imsSwitchOnByDefault_.end()) {
556                 active = imsSwitchOnByDefault_[slotId];
557                 return active;
558             }
559         }
560     }
561     TELEPHONY_LOGE("do not find hideImsSwitch or imsSwitchOnByDefault config");
562     return active;
563 }
564 
SaveImsSwitch(int32_t slotId,int32_t imsSwitchValue)565 int32_t CellularCallConfig::SaveImsSwitch(int32_t slotId, int32_t imsSwitchValue)
566 {
567     int32_t lastImsSwitchValue = IMS_SWITCH_STATUS_UNKNOWN;
568     int32_t queryRet = CoreManagerInner::GetInstance().QueryImsSwitch(slotId, lastImsSwitchValue);
569     if (queryRet != TELEPHONY_SUCCESS) {
570         TELEPHONY_LOGE("query ims switch failed");
571         return SAVE_IMS_SWITCH_FAILED;
572     }
573     if (imsSwitchValue == lastImsSwitchValue) {
574         TELEPHONY_LOGI("ims switch status do not change, imsSwitchValue: %{public}d", imsSwitchValue);
575         return SAVE_IMS_SWITCH_SUCCESS_NOT_CHANGED;
576     }
577     int32_t saveRet = CoreManagerInner::GetInstance().SaveImsSwitch(slotId, imsSwitchValue);
578     if (saveRet != TELEPHONY_SUCCESS) {
579         TELEPHONY_LOGE("save ims switch status to database failed!");
580         return SAVE_IMS_SWITCH_FAILED;
581     }
582     saveImsSwitchStatusToLocal(slotId, imsSwitchValue);
583     return SAVE_IMS_SWITCH_SUCCESS_CHANGED;
584 }
585 
saveImsSwitchStatusToLocalForPowerOn(int32_t slotId)586 void CellularCallConfig::saveImsSwitchStatusToLocalForPowerOn(int32_t slotId)
587 {
588     int32_t imsSwitchStatus = IMS_SWITCH_STATUS_UNKNOWN;
589     int32_t ret = CoreManagerInner::GetInstance().QueryImsSwitch(slotId, imsSwitchStatus);
590     if (ret != TELEPHONY_SUCCESS || imsSwitchStatus == IMS_SWITCH_STATUS_UNKNOWN) {
591         TELEPHONY_LOGI("get ims switch state failed from database, return operator config default value");
592         imsSwitchStatus = imsSwitchOnByDefault_[slotId] ? IMS_SWITCH_STATUS_ON : IMS_SWITCH_STATUS_OFF;
593     }
594 
595     TELEPHONY_LOGI(
596         "save slotId[%{public}d] imsSwitchStatus:%{public}d to local for Power on", slotId, imsSwitchStatus);
597     std::string imsSwitchStateKey = IMSSWITCH_STATE + std::to_string(slotId);
598     std::string imsSwitchState = std::to_string(imsSwitchStatus);
599     SetParameter(imsSwitchStateKey.c_str(), imsSwitchState.c_str());
600 }
601 
saveImsSwitchStatusToLocal(int32_t slotId,int32_t imsSwitchStatus)602 void CellularCallConfig::saveImsSwitchStatusToLocal(int32_t slotId, int32_t imsSwitchStatus)
603 {
604     TELEPHONY_LOGI("save slotId[%{public}d] imsSwitchStatus:%{public}d to local", slotId, imsSwitchStatus);
605     std::string imsSwitchStateKey = IMSSWITCH_STATE + std::to_string(slotId);
606     std::string imsSwitchState = std::to_string(imsSwitchStatus);
607     SetParameter(imsSwitchStateKey.c_str(), imsSwitchState.c_str());
608 }
609 
SaveVoNRState(int32_t slotId,int32_t state)610 void CellularCallConfig::SaveVoNRState(int32_t slotId, int32_t state)
611 {
612     CellularCallHiSysEvent::WriteVoNRSwitchChangeEvent(state);
613     TELEPHONY_LOGI("slotId: %{public}d, switchState: %{public}d", slotId, state);
614     std::string vonrState = std::to_string(state);
615     std::string vonrStateKey = VONR_STATE + std::to_string(slotId);
616     SetParameter(vonrStateKey.c_str(), vonrState.c_str());
617 }
618 
ObtainVoNRState(int32_t slotId)619 int32_t CellularCallConfig::ObtainVoNRState(int32_t slotId)
620 {
621     std::string vonrStateKey = VONR_STATE + std::to_string(slotId);
622     int32_t vonrState = GetIntParameter(vonrStateKey.c_str(), VONR_SWITCH_STATUS_ON);
623     TELEPHONY_LOGI("slotId: %{public}d, switchState: %{public}d", slotId, vonrState);
624     return vonrState;
625 }
626 
HandleSetLteImsSwitchResult(int32_t slotId,HRilErrType result)627 void CellularCallConfig::HandleSetLteImsSwitchResult(int32_t slotId, HRilErrType result)
628 {
629     TELEPHONY_LOGI("CellularCallConfig::HandleSetLteImsSwitchResult entry, slotId: %{public}d", slotId);
630     if (result != HRilErrType::NONE) {
631         TELEPHONY_LOGE("HandleSetLteImsSwitchResult set ims switch to modem failed!");
632         // need to reset the Ims Switch parameter and notify APP to update UI.
633     }
634 }
635 
HandleSetVoNRSwitchResult(int32_t slotId,HRilErrType result)636 void CellularCallConfig::HandleSetVoNRSwitchResult(int32_t slotId, HRilErrType result)
637 {
638     TELEPHONY_LOGD("CellularCallConfig::HandleSetVoNRSwitchResult entry, slotId: %{public}d", slotId);
639     if (result != HRilErrType::NONE) {
640         TELEPHONY_LOGE("HandleSetVoNRSwitchResult set vonr switch to modem failed!");
641         return;
642     }
643     SaveVoNRState(slotId, vonrSwithStatus_[slotId]);
644     ImsCapabilityList imsCapabilityList;
645     UpdateImsVoiceCapabilities(slotId, IsGbaValid(slotId), imsCapabilityList);
646     configRequest_.UpdateImsCapabilities(slotId, imsCapabilityList);
647 }
648 
GetDomainPreferenceModeResponse(int32_t slotId,int32_t mode)649 void CellularCallConfig::GetDomainPreferenceModeResponse(int32_t slotId, int32_t mode)
650 {
651     modeMap_[slotId] = mode;
652 }
653 
GetImsSwitchStatusResponse(int32_t slotId,int32_t active)654 void CellularCallConfig::GetImsSwitchStatusResponse(int32_t slotId, int32_t active) {}
655 
GetPreferenceMode(int32_t slotId) const656 int32_t CellularCallConfig::GetPreferenceMode(int32_t slotId) const
657 {
658     return modeMap_[slotId];
659 }
660 
GetSwitchStatus(int32_t slotId)661 int32_t CellularCallConfig::GetSwitchStatus(int32_t slotId)
662 {
663     std::string imsSwitchStateKey = IMSSWITCH_STATE + std::to_string(slotId);
664     int32_t imsSwitchStatus = GetIntParameter(imsSwitchStateKey.c_str(), IMS_SWITCH_STATUS_UNKNOWN);
665     if (imsSwitchStatus == IMS_SWITCH_STATUS_UNKNOWN) {
666         TELEPHONY_LOGI("get ims switch state failed from local, try to get it from database");
667         int32_t ret = CoreManagerInner::GetInstance().QueryImsSwitch(slotId, imsSwitchStatus);
668         if (ret != TELEPHONY_SUCCESS || imsSwitchStatus == IMS_SWITCH_STATUS_UNKNOWN) {
669             TELEPHONY_LOGI("get ims switch state failed from database, return operator config default value");
670             imsSwitchStatus = imsSwitchOnByDefault_[slotId] ? IMS_SWITCH_STATUS_ON : IMS_SWITCH_STATUS_OFF;
671         }
672         // save DB or operator config default ims switch status to local
673         saveImsSwitchStatusToLocal(slotId, imsSwitchStatus);
674     }
675     TELEPHONY_LOGI("slotId[%{public}d] GetSwitchStatus imsSwitchStatus:%{public}d", slotId, imsSwitchStatus);
676     return imsSwitchStatus;
677 }
678 
SetImsConfig(ImsConfigItem item,const std::string & value)679 int32_t CellularCallConfig::SetImsConfig(ImsConfigItem item, const std::string &value)
680 {
681     return configRequest_.SetImsConfigRequest(item, value);
682 }
683 
SetImsConfig(ImsConfigItem item,int32_t value)684 int32_t CellularCallConfig::SetImsConfig(ImsConfigItem item, int32_t value)
685 {
686     return configRequest_.SetImsConfigRequest(item, value);
687 }
688 
GetImsConfig(ImsConfigItem item)689 int32_t CellularCallConfig::GetImsConfig(ImsConfigItem item)
690 {
691     return configRequest_.GetImsConfigRequest(item);
692 }
693 
SetImsFeatureValue(FeatureType type,int32_t value)694 int32_t CellularCallConfig::SetImsFeatureValue(FeatureType type, int32_t value)
695 {
696     return configRequest_.SetImsFeatureValueRequest(type, value);
697 }
698 
GetImsFeatureValue(FeatureType type)699 int32_t CellularCallConfig::GetImsFeatureValue(FeatureType type)
700 {
701     int32_t imsFeatureValue;
702     int32_t ret = configRequest_.GetImsFeatureValueRequest(type, imsFeatureValue);
703     GetImsFeatureValueResponse response;
704     response.result = ret;
705     response.value = imsFeatureValue;
706     DelayedSingleton<CellularCallRegister>::GetInstance()->ReportGetImsFeatureResult(response);
707     return ret;
708 }
709 
SetTempMode(int32_t slotId)710 void CellularCallConfig::SetTempMode(int32_t slotId)
711 {
712     modeMap_[slotId] = modeTempMap_[slotId];
713 }
714 
InitModeActive()715 void CellularCallConfig::InitModeActive()
716 {
717     int32_t slotId = DEFAULT_SIM_SLOT_ID;
718     modeMap_[slotId] = DomainPreferenceMode::IMS_PS_VOICE_PREFERRED;
719     eccListRadioMap_.clear();
720     eccList3gppHasSim_.clear();
721     eccList3gppNoSim_.clear();
722     allEccList_.clear();
723     eccList3gppHasSim_.push_back(BuildDefaultEmergencyCall("112", SimpresentType::TYPE_HAS_CARD));
724     eccList3gppHasSim_.push_back(BuildDefaultEmergencyCall("911", SimpresentType::TYPE_HAS_CARD));
725     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("112", SimpresentType::TYPE_NO_CARD));
726     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("911", SimpresentType::TYPE_NO_CARD));
727     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("000", SimpresentType::TYPE_NO_CARD));
728     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("08", SimpresentType::TYPE_NO_CARD));
729     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("110", SimpresentType::TYPE_NO_CARD));
730     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("118", SimpresentType::TYPE_NO_CARD));
731     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("119", SimpresentType::TYPE_NO_CARD));
732     eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("999", SimpresentType::TYPE_NO_CARD));
733     TELEPHONY_LOGD("InitModeActive finish");
734 }
735 
BuildDefaultEmergencyCall(const std::string & number,SimpresentType simType)736 EmergencyCall CellularCallConfig::BuildDefaultEmergencyCall(const std::string &number, SimpresentType simType)
737 {
738     TELEPHONY_LOGD("BuildDefaultEmergencyCall, eccNum:%{public}s", number.c_str());
739     EmergencyCall emergencyCall;
740     emergencyCall.eccNum = number;
741     emergencyCall.eccType = EccType::TYPE_CATEGORY;
742     emergencyCall.simpresent = simType;
743     emergencyCall.mcc = "";
744     emergencyCall.abnormalService = AbnormalServiceType::TYPE_ALL;
745     std::string::size_type pos = number.find('+');
746     if (pos != std::string::npos) {
747         int32_t startOps = 0;
748         std::string category = number.substr(startOps, pos);
749         emergencyCall.eccType = static_cast<EccType>(std::atoi(category.c_str()));
750         emergencyCall.eccNum = number.substr(pos, number.size());
751     }
752     return emergencyCall;
753 }
754 
MergeEccCallList(int32_t slotId)755 void CellularCallConfig::MergeEccCallList(int32_t slotId)
756 {
757     std::map<int32_t, std::vector<EmergencyCall>> tempEccList;
758     std::string mcc = GetMcc(slotId);
759     for (auto ecc : eccListRadioMap_[slotId]) {
760         ecc.mcc = mcc;
761         tempEccList[slotId].push_back(ecc);
762     }
763     TELEPHONY_LOGI("MergeEccCallList merge radio slotId  %{public}d size  %{public}d", slotId,
764         static_cast<int32_t>(eccListRadioMap_[slotId].size()));
765     SimState simState = SimState::SIM_STATE_UNKNOWN;
766     CoreManagerInner::GetInstance().GetSimState(slotId, simState);
767     bool hasSim = simState == SimState::SIM_STATE_READY || simState == SimState::SIM_STATE_LOADED;
768     if (hasSim) {
769         if (!mcc.empty()) {
770             for (auto ecc : eccList3gppHasSim_) {
771                 ecc.mcc = mcc;
772                 tempEccList[slotId].push_back(ecc);
773             }
774         }
775     } else {
776         for (auto ecc : eccList3gppNoSim_) {
777             ecc.mcc = mcc;
778             tempEccList[slotId].push_back(ecc);
779         }
780     }
781     std::u16string u16Hplmn = u"";
782     CoreManagerInner::GetInstance().GetSimOperatorNumeric(slotId, u16Hplmn);
783     std::string hplmn = Str16ToStr8(u16Hplmn);
784     int32_t roamingState = CoreManagerInner::GetInstance().GetPsRoamingState(slotId);
785     bool isRoaming = roamingState > static_cast<int32_t>(RoamingType::ROAMING_STATE_UNKNOWN) &&
786         roamingState <= static_cast<int32_t>(RoamingType::ROAMING_STATE_INTERNATIONAL);
787     if (hasSim && !isRoaming && !hplmn.empty()) {
788         std::vector<EccNum> eccVec;
789         DelayedSingleton<CellularCallRdbHelper>::GetInstance()->QueryEccList(hplmn, eccVec);
790         if (!eccVec.empty()) {
791             std::string ecc = eccVec[0].ecc_fake;
792             std::vector<std::string> callList = StandardizeUtils::Split(ecc, ",");
793             for (auto it : callList) {
794                 EmergencyCall call = BuildDefaultEmergencyCall(it, SimpresentType::TYPE_HAS_CARD);
795                 call.mcc = mcc;
796                 tempEccList[slotId].push_back(call);
797             }
798         }
799     }
800     UniqueEccCallList(slotId, tempEccList[slotId]);
801 }
802 
UniqueEccCallList(int32_t slotId,std::vector<EmergencyCall> & eccList)803 void CellularCallConfig::UniqueEccCallList(int32_t slotId, std::vector<EmergencyCall> &eccList)
804 {
805     allEccList_[slotId].clear();
806     for (auto call : eccList) {
807         if (std::find(allEccList_[slotId].begin(), allEccList_[slotId].end(), call) ==
808             allEccList_[slotId].end()) {
809             allEccList_[slotId].push_back(call);
810         }
811     }
812     for (auto call : allEccList_[slotId]) {
813         TELEPHONY_LOGI("UniqueEccCallList end slotId %{public}d eccNum:%{public}s, mcc:%{public}s",
814             slotId, call.eccNum.c_str(), call.mcc.c_str());
815     }
816 }
817 
GetMcc(int32_t slotId)818 std::string CellularCallConfig::GetMcc(int32_t slotId)
819 {
820     std::u16string operatorNumeric;
821     CoreManagerInner::GetInstance().GetSimOperatorNumeric(slotId, operatorNumeric);
822     std::string imsi = Str16ToStr8(operatorNumeric);
823     int len = static_cast<int>(imsi.length());
824     std::string mcc = imsi;
825     if (len >= MCC_LEN) {
826         mcc = imsi.substr(0, MCC_LEN);
827     }
828     TELEPHONY_LOGI("getMcc slotd %{public}d mcc %{public}s end", slotId, mcc.c_str());
829     return mcc;
830 }
831 
SetMute(int32_t slotId,int32_t mute)832 int32_t CellularCallConfig::SetMute(int32_t slotId, int32_t mute)
833 {
834     return configRequest_.SetMuteRequest(slotId, mute);
835 }
836 
GetMute(int32_t slotId)837 int32_t CellularCallConfig::GetMute(int32_t slotId)
838 {
839     return configRequest_.GetMuteRequest(slotId);
840 }
841 
GetEmergencyCallList(int32_t slotId)842 int32_t CellularCallConfig::GetEmergencyCallList(int32_t slotId)
843 {
844     return configRequest_.GetEmergencyCallListRequest(slotId);
845 }
846 
SetEmergencyCallList(int32_t slotId,std::vector<EmergencyCall> & eccVec)847 int32_t CellularCallConfig::SetEmergencyCallList(int32_t slotId, std::vector<EmergencyCall> &eccVec)
848 {
849     TELEPHONY_LOGI("SetEmergencyCallList start %{public}d", slotId);
850     return configRequest_.SetEmergencyCallListRequest(slotId, eccVec);
851 }
852 
CheckAndUpdateSimState(int32_t slotId)853 bool CellularCallConfig::CheckAndUpdateSimState(int32_t slotId)
854 {
855     SimState simState = SimState::SIM_STATE_UNKNOWN;
856     CoreManagerInner::GetInstance().GetSimState(slotId, simState);
857     int32_t simStateForEcc;
858     switch (simState) {
859         case SimState::SIM_STATE_READY:
860         case SimState::SIM_STATE_LOADED: {
861             simStateForEcc = SIM_PRESENT;
862             break;
863         }
864         default: {
865             simStateForEcc = SIM_ABSENT;
866             break;
867         }
868     }
869     bool result = (simState_[slotId] != simStateForEcc);
870     simState_[slotId] = simStateForEcc;
871     return result;
872 }
873 
UpdateEmergencyCallFromRadio(int32_t slotId,const EmergencyInfoList & eccList)874 void CellularCallConfig::UpdateEmergencyCallFromRadio(int32_t slotId, const EmergencyInfoList &eccList)
875 {
876     TELEPHONY_LOGD("UpdateEmergencyCallFromRadio %{publid}d size %{public}d", slotId, eccList.callSize);
877     std::lock_guard<std::mutex> lock(mutex_);
878     eccListRadioMap_[slotId].clear();
879     for (auto ecc : eccList.calls) {
880         TELEPHONY_LOGD("UpdateEmergencyCallFromRadio , data: eccNum %{public}s mcc %{public}s", ecc.eccNum.c_str(),
881             ecc.mcc.c_str());
882         eccListRadioMap_[slotId].push_back(BuildEmergencyCall(slotId, ecc));
883     }
884     MergeEccCallList(slotId);
885 }
886 
GetEccCallList(int32_t slotId)887 std::vector<EmergencyCall> CellularCallConfig::GetEccCallList(int32_t slotId)
888 {
889     TELEPHONY_LOGD("GetEccCallList  start %{publiic}d", slotId);
890     std::lock_guard<std::mutex> lock(mutex_);
891     TELEPHONY_LOGD("GetEccCallList size %{publiic}zu", allEccList_[slotId].size());
892     for (auto ecc : allEccList_[slotId]) {
893         TELEPHONY_LOGI("GetEccCallList, data: eccNum %{public}s mcc %{public}s", ecc.eccNum.c_str(), ecc.mcc.c_str());
894     }
895     return allEccList_[slotId];
896 }
897 
BooleanToImsSwitchValue(bool value)898 int32_t CellularCallConfig::BooleanToImsSwitchValue(bool value)
899 {
900     return value ? IMS_SWITCH_STATUS_ON : IMS_SWITCH_STATUS_OFF;
901 }
902 
GetImsSwitchOnByDefaultConfig(int32_t slotId)903 bool CellularCallConfig::GetImsSwitchOnByDefaultConfig(int32_t slotId)
904 {
905     if (!IsValidSlotId(slotId)) {
906         TELEPHONY_LOGE("invalid slot id");
907         return true;
908     }
909     return imsSwitchOnByDefault_[slotId];
910 }
911 
GethideImsSwitchConfig(int32_t slotId)912 bool CellularCallConfig::GethideImsSwitchConfig(int32_t slotId)
913 {
914     if (!IsValidSlotId(slotId)) {
915         TELEPHONY_LOGE("invalid slot id");
916         return false;
917     }
918     return hideImsSwitch_[slotId];
919 }
920 
GetvolteSupportedConfig(int32_t slotId)921 bool CellularCallConfig::GetvolteSupportedConfig(int32_t slotId)
922 {
923     if (!IsValidSlotId(slotId)) {
924         TELEPHONY_LOGE("invalid slot id");
925         return false;
926     }
927     return volteSupported_[slotId];
928 }
929 
GetNrModeSupportedListConfig(int32_t slotId)930 std::vector<int32_t> CellularCallConfig::GetNrModeSupportedListConfig(int32_t slotId)
931 {
932     if (!IsValidSlotId(slotId)) {
933         TELEPHONY_LOGE("invalid slot id");
934         return std::vector<int32_t> { CARRIER_NR_AVAILABILITY_NSA, CARRIER_NR_AVAILABILITY_SA };
935     }
936     return nrModeSupportedList_[slotId];
937 }
938 
GetVolteProvisioningSupportedConfig(int32_t slotId)939 bool CellularCallConfig::GetVolteProvisioningSupportedConfig(int32_t slotId)
940 {
941     if (!IsValidSlotId(slotId)) {
942         TELEPHONY_LOGE("invalid slot id");
943         return false;
944     }
945     return volteProvisioningSupported_[slotId];
946 }
947 
GetSsOverUtSupportedConfig(int32_t slotId)948 bool CellularCallConfig::GetSsOverUtSupportedConfig(int32_t slotId)
949 {
950     if (!IsValidSlotId(slotId)) {
951         TELEPHONY_LOGE("invalid slot id");
952         return false;
953     }
954     return ssOverUtSupported_[slotId];
955 }
956 
GetImsGbaRequiredConfig(int32_t slotId)957 bool CellularCallConfig::GetImsGbaRequiredConfig(int32_t slotId)
958 {
959     if (!IsValidSlotId(slotId)) {
960         TELEPHONY_LOGE("invalid slot id");
961         return false;
962     }
963     return imsGbaRequired_[slotId];
964 }
965 
GetUtProvisioningSupportedConfig(int32_t slotId)966 bool CellularCallConfig::GetUtProvisioningSupportedConfig(int32_t slotId)
967 {
968     if (!IsValidSlotId(slotId)) {
969         TELEPHONY_LOGE("invalid slot id");
970         return false;
971     }
972     return utProvisioningSupported_[slotId];
973 }
974 
GetImsPreferForEmergencyConfig(int32_t slotId)975 bool CellularCallConfig::GetImsPreferForEmergencyConfig(int32_t slotId)
976 {
977     if (!IsValidSlotId(slotId)) {
978         TELEPHONY_LOGE("invalid slot id");
979         return true;
980     }
981     return imsPreferForEmergency_[slotId];
982 }
983 
GetCallWaitingServiceClassConfig(int32_t slotId)984 std::int32_t CellularCallConfig::GetCallWaitingServiceClassConfig(int32_t slotId)
985 {
986     if (!IsValidSlotId(slotId)) {
987         TELEPHONY_LOGE("invalid slot id");
988         return 1;
989     }
990     return callWaitingServiceClass_[slotId];
991 }
992 
GetImsCallDisconnectResoninfoMappingConfig(int32_t slotId)993 std::vector<std::string> CellularCallConfig::GetImsCallDisconnectResoninfoMappingConfig(int32_t slotId)
994 {
995     std::lock_guard<std::mutex> lock(operatorMutex_);
996     if (!IsValidSlotId(slotId)) {
997         TELEPHONY_LOGE("invalid slot id");
998         return std::vector<std::string> {};
999     }
1000     return imsCallDisconnectResoninfoMapping_[slotId];
1001 }
1002 
GetForceVolteSwitchOnConfig(int32_t slotId)1003 bool CellularCallConfig::GetForceVolteSwitchOnConfig(int32_t slotId)
1004 {
1005     if (!IsValidSlotId(slotId)) {
1006         TELEPHONY_LOGE("invalid slot id");
1007         return false;
1008     }
1009     return forceVolteSwitchOn_[slotId];
1010 }
1011 
IsValidSlotId(int32_t slotId)1012 bool CellularCallConfig::IsValidSlotId(int32_t slotId)
1013 {
1014     int32_t count = SIM_SLOT_COUNT;
1015     if ((slotId >= DEFAULT_SIM_SLOT_ID) && (slotId < count)) {
1016         return true;
1017     }
1018 
1019     TELEPHONY_LOGE("SlotId is InValid = %{public}d", slotId);
1020     return false;
1021 }
1022 
SetReadyToCall(int32_t slotId,bool isReadyToCall)1023 void CellularCallConfig::SetReadyToCall(int32_t slotId, bool isReadyToCall)
1024 {
1025     if (!IsValidSlotId(slotId)) {
1026         TELEPHONY_LOGE("invalid slot id");
1027         return;
1028     }
1029     readyToCall_[slotId] = isReadyToCall;
1030 }
1031 
IsReadyToCall(int32_t slotId)1032 bool CellularCallConfig::IsReadyToCall(int32_t slotId)
1033 {
1034     if (!IsValidSlotId(slotId)) {
1035         TELEPHONY_LOGE("invalid slot id");
1036         return false;
1037     }
1038     return readyToCall_[slotId];
1039 }
1040 } // namespace Telephony
1041 } // namespace OHOS
1042