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