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