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