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_register.h"
20 #include "cellular_call_service.h"
21 #include "core_manager_inner.h"
22 #include "module_service_utils.h"
23 #include "parameters.h"
24 #include "string_ex.h"
25 #include "telephony_types.h"
26
27 namespace OHOS {
28 namespace Telephony {
29 const int32_t SIM_PRESENT = 1;
30 const int32_t SIM_ABSENT = 0;
31 const int32_t IMS_SWITCH_VALUE_DISABLED = 0;
32 const int32_t IMS_SWITCH_VALUE_ENABLED = 1;
33 const int32_t IMS_SWITCH_STATUS_OFF = 0;
34 const int32_t IMS_SWITCH_STATUS_ON = 1;
35 const int32_t SAVE_IMS_SWITCH_FAILED = 0;
36 const int32_t SAVE_IMS_SWITCH_SUCCESS_CHANGED = 1;
37 const int32_t SAVE_IMS_SWITCH_SUCCESS_NOT_CHANGED = 2;
38 const int32_t INVALID_SIM_ID = 0;
39 const int32_t IMS_GBA_BIT = 0x02;
40 const int32_t SYSTEM_PARAMETER_LENGTH = 0x02;
41 const int MCC_LEN = 3;
42 const std::string LAST_ICCID_KEY = "persist.telephony.last_iccid";
43
44 std::map<int32_t, int32_t> CellularCallConfig::modeMap_;
45 std::map<int32_t, int32_t> CellularCallConfig::modeTempMap_;
46 std::map<int32_t, bool> CellularCallConfig::imsSwitchOnByDefault_;
47 std::map<int32_t, bool> CellularCallConfig::hideImsSwitch_;
48 std::map<int32_t, bool> CellularCallConfig::volteSupported_;
49 std::map<int32_t, std::vector<int32_t>> CellularCallConfig::nrModeSupportedList_;
50 std::map<int32_t, bool> CellularCallConfig::volteProvisioningSupported_;
51 std::map<int32_t, bool> CellularCallConfig::ssOverUtSupported_;
52 std::map<int32_t, bool> CellularCallConfig::imsGbaRequired_;
53 std::map<int32_t, bool> CellularCallConfig::utProvisioningSupported_;
54 std::map<int32_t, bool> CellularCallConfig::imsPreferForEmergency_;
55 std::map<int32_t, int32_t> CellularCallConfig::callWaitingServiceClass_;
56 std::map<int32_t, std::vector<std::string>> CellularCallConfig::imsCallDisconnectResoninfoMapping_;
57 std::map<int32_t, bool> CellularCallConfig::forceVolteSwitchOn_;
58 std::mutex mutex_;
59 std::map<int32_t, std::vector<EmergencyCall>> CellularCallConfig::eccListRadioMap_;
60 std::map<int32_t, std::vector<EmergencyCall>> CellularCallConfig::eccListConfigMap_;
61 std::vector<EmergencyCall> CellularCallConfig::eccList3gppHasSim_;
62 std::vector<EmergencyCall> CellularCallConfig::eccList3gppNoSim_;
63 std::map<int32_t, std::vector<EmergencyCall>> CellularCallConfig::allEccList_;
64 std::map<int32_t, int32_t> CellularCallConfig::simState_;
65 bool CellularCallConfig::isOperatorConfigInit_ = false;
66
InitDefaultOperatorConfig()67 void CellularCallConfig::InitDefaultOperatorConfig()
68 {
69 for (int32_t i = DEFAULT_SIM_SLOT_ID; i < SIM_SLOT_COUNT; ++i) {
70 CellularCallConfig::imsSwitchOnByDefault_.insert(std::pair<int, bool>(i, true));
71 CellularCallConfig::hideImsSwitch_.insert(std::pair<int, bool>(i, false));
72 CellularCallConfig::volteSupported_.insert(std::pair<int, bool>(i, false));
73 CellularCallConfig::nrModeSupportedList_.insert(std::pair<int, std::vector<int32_t>>(
74 i, std::vector<int32_t> { CARRIER_NR_AVAILABILITY_NSA, CARRIER_NR_AVAILABILITY_SA }));
75 CellularCallConfig::volteProvisioningSupported_.insert(std::pair<int, bool>(i, false));
76 CellularCallConfig::ssOverUtSupported_.insert(std::pair<int, bool>(i, false));
77 CellularCallConfig::imsGbaRequired_.insert(std::pair<int, bool>(i, false));
78 CellularCallConfig::utProvisioningSupported_.insert(std::pair<int, bool>(i, false));
79 CellularCallConfig::imsPreferForEmergency_.insert(std::pair<int, bool>(i, true));
80 CellularCallConfig::callWaitingServiceClass_.insert(
81 std::pair<int, int32_t>(i, DEFAULT_CALL_WAITING_SERVICE_CLASS_CONFIG));
82 CellularCallConfig::imsCallDisconnectResoninfoMapping_.insert(
83 std::pair<int, std::vector<std::string>>(i, IMS_CALL_DISCONNECT_REASONINFO_MAPPING_CONFIG));
84 CellularCallConfig::forceVolteSwitchOn_.insert(std::pair<int, bool>(i, false));
85 }
86 }
87
CellularCallConfig()88 CellularCallConfig::CellularCallConfig()
89 {
90 if (!isOperatorConfigInit_) {
91 InitDefaultOperatorConfig();
92 isOperatorConfigInit_ = true;
93 }
94 }
95
SetDomainPreferenceMode(int32_t slotId,int32_t mode)96 int32_t CellularCallConfig::SetDomainPreferenceMode(int32_t slotId, int32_t mode)
97 {
98 if (mode < DomainPreferenceMode::CS_VOICE_ONLY || mode > DomainPreferenceMode::IMS_PS_VOICE_ONLY) {
99 TELEPHONY_LOGE("SetDomainPreferenceMode return, mode out of range!");
100 return CALL_ERR_PARAMETER_OUT_OF_RANGE;
101 }
102 modeTempMap_[slotId] = mode;
103 return configRequest_.SetDomainPreferenceModeRequest(slotId, mode);
104 }
105
GetDomainPreferenceMode(int32_t slotId)106 int32_t CellularCallConfig::GetDomainPreferenceMode(int32_t slotId)
107 {
108 return configRequest_.GetDomainPreferenceModeRequest(slotId);
109 }
110
SetImsSwitchStatus(int32_t slotId,bool active)111 int32_t CellularCallConfig::SetImsSwitchStatus(int32_t slotId, bool active)
112 {
113 TELEPHONY_LOGI(
114 "CellularCallConfig::SetImsSwitchStatus entry, slotId: %{public}d, active: %{public}d", slotId, active);
115 if (!volteSupported_[slotId]) {
116 TELEPHONY_LOGE("Enable ims switch failed due to volte is not supported.");
117 return CALL_ERR_VOLTE_NOT_SUPPORT;
118 }
119 if (active && !IsVolteProvisioned(slotId)) {
120 TELEPHONY_LOGE("Enable ims switch failed due to volte provisioning disabled.");
121 return CALL_ERR_VOLTE_PROVISIONING_DISABLED;
122 }
123 int32_t simId = CoreManagerInner::GetInstance().GetSimId(slotId);
124 if (simId <= INVALID_SIM_ID) {
125 TELEPHONY_LOGE("failed due to invalid sim id %{public}d", simId);
126 return TELEPHONY_ERR_SLOTID_INVALID;
127 }
128
129 active = ChangeImsSwitchWithOperatorConfig(slotId, active);
130 int32_t ret = SaveImsSwitch(slotId, BooleanToImsSwitchValue(active));
131 if (ret == SAVE_IMS_SWITCH_FAILED) {
132 return TELEPHONY_ERR_DATABASE_WRITE_FAIL;
133 } else if (ret == SAVE_IMS_SWITCH_SUCCESS_NOT_CHANGED) {
134 return TELEPHONY_SUCCESS;
135 }
136
137 SimState simState = SimState::SIM_STATE_UNKNOWN;
138 CoreManagerInner::GetInstance().GetSimState(slotId, simState);
139 TELEPHONY_LOGI("active: %{public}d simState : %{public}d", active, simState);
140 if (simState == SimState::SIM_STATE_LOADED || simState == SimState::SIM_STATE_READY) {
141 UpdateImsCapabilities(slotId, !active);
142 }
143 return TELEPHONY_SUCCESS;
144 }
145
GetImsSwitchStatus(int32_t slotId,bool & enabled)146 int32_t CellularCallConfig::GetImsSwitchStatus(int32_t slotId, bool &enabled)
147 {
148 TELEPHONY_LOGI("entry, slotId: %{public}d", slotId);
149 auto itorHide = hideImsSwitch_.find(slotId);
150 if (itorHide != hideImsSwitch_.end()) {
151 if (itorHide->second) {
152 auto itorSwitch = imsSwitchOnByDefault_.find(slotId);
153 if (itorSwitch != imsSwitchOnByDefault_.end()) {
154 enabled = imsSwitchOnByDefault_[slotId];
155 }
156 } else {
157 int32_t imsSwitchStatus = GetSwitchStatus(slotId);
158 enabled = imsSwitchStatus;
159 }
160 } else {
161 TELEPHONY_LOGE("do not find hideImsSwitch");
162 int32_t imsSwitchStatus = GetSwitchStatus(slotId);
163 enabled = imsSwitchStatus;
164 }
165 return TELEPHONY_SUCCESS;
166 }
167
HandleSimStateChanged(int32_t slotId)168 void CellularCallConfig::HandleSimStateChanged(int32_t slotId)
169 {
170 TELEPHONY_LOGI("CellularCallConfig::HandleSimStateChanged entry, slotId: %{public}d", slotId);
171 if (IsNeedUpdateEccListWhenSimStateChanged(slotId)) {
172 MergeEccCallList(slotId);
173 SetEmergencyCallList(slotId);
174 }
175 }
176
HandleSimRecordsLoaded(int32_t slotId)177 void CellularCallConfig::HandleSimRecordsLoaded(int32_t slotId)
178 {
179 SimState simState = SimState::SIM_STATE_UNKNOWN;
180 CoreManagerInner::GetInstance().GetSimState(slotId, simState);
181 TELEPHONY_LOGI("HandleSimRecordsLoaded slotId: %{public}d, sim state is :%{public}d", slotId, simState);
182 }
183
HandleOperatorConfigChanged(int32_t slotId)184 void CellularCallConfig::HandleOperatorConfigChanged(int32_t slotId)
185 {
186 OperatorConfig operatorConfig;
187 int32_t ret = CoreManagerInner::GetInstance().GetOperatorConfigs(slotId, operatorConfig);
188 if (ret != TELEPHONY_SUCCESS) {
189 TELEPHONY_LOGE("failed due to get operator config");
190 return;
191 }
192 UpdateEccWhenOperatorConfigChange(slotId, operatorConfig);
193 int32_t result = ParseAndCacheOperatorConfigs(slotId, operatorConfig);
194 if (result != TELEPHONY_SUCCESS) {
195 TELEPHONY_LOGE("failed due to parse operator config");
196 return;
197 }
198
199 ResetImsSwitch(slotId);
200 UpdateImsCapabilities(slotId, true);
201 }
202
ParseAndCacheOperatorConfigs(int32_t slotId,OperatorConfig & poc)203 int32_t CellularCallConfig::ParseAndCacheOperatorConfigs(int32_t slotId, OperatorConfig &poc)
204 {
205 TELEPHONY_LOGI("CellularCallConfig::ParseAndCacheOperatorConfigs start. slotId %{public}d", slotId);
206 if (!IsValidSlotId(slotId)) {
207 TELEPHONY_LOGE(" invalid slot id %{public}d", slotId);
208 return TELEPHONY_ERROR;
209 }
210
211 ParseBoolOperatorConfigs(slotId, imsSwitchOnByDefault_, poc, KEY_IMS_SWITCH_ON_BY_DEFAULT_BOOL);
212 ParseBoolOperatorConfigs(slotId, hideImsSwitch_, poc, KEY_HIDE_IMS_SWITCH_BOOL);
213 ParseBoolOperatorConfigs(slotId, volteSupported_, poc, KEY_VOLTE_SUPPORTED_BOOL);
214 ParseBoolOperatorConfigs(slotId, volteProvisioningSupported_, poc, KEY_VOLTE_PROVISIONING_SUPPORTED_BOOL);
215 ParseBoolOperatorConfigs(slotId, ssOverUtSupported_, poc, KEY_SS_OVER_UT_SUPPORTED_BOOL);
216 ParseBoolOperatorConfigs(slotId, imsGbaRequired_, poc, KEY_IMS_GBA_REQUIRED_BOOL);
217 ParseBoolOperatorConfigs(slotId, utProvisioningSupported_, poc, KEY_UT_PROVISIONING_SUPPORTED_BOOL);
218 ParseBoolOperatorConfigs(slotId, imsPreferForEmergency_, poc, KEY_IMS_PREFER_FOR_EMERGENCY_BOOL);
219 ParseBoolOperatorConfigs(slotId, forceVolteSwitchOn_, poc, KEY_FORCE_VOLTE_SWITCH_ON_BOOL);
220
221 if (poc.intArrayValue.count(KEY_NR_MODE_SUPPORTED_LIST_INT_ARRAY) > 0) {
222 nrModeSupportedList_[slotId] = poc.intArrayValue[KEY_NR_MODE_SUPPORTED_LIST_INT_ARRAY];
223 }
224 if (poc.intValue.count(KEY_CALL_WAITING_SERVICE_CLASS_INT) > 0) {
225 callWaitingServiceClass_[slotId] = poc.intValue[KEY_CALL_WAITING_SERVICE_CLASS_INT];
226 }
227 if (poc.stringArrayValue.count(KEY_IMS_CALL_DISCONNECT_REASONINFO_MAPPING_STRING_ARRAY) > 0) {
228 imsCallDisconnectResoninfoMapping_[slotId] =
229 poc.stringArrayValue[KEY_IMS_CALL_DISCONNECT_REASONINFO_MAPPING_STRING_ARRAY];
230 }
231 return TELEPHONY_SUCCESS;
232 }
233
ParseBoolOperatorConfigs(int32_t slotId,std::map<int32_t,bool> & config,OperatorConfig & poc,std::string configName)234 void CellularCallConfig::ParseBoolOperatorConfigs(
235 int32_t slotId, std::map<int32_t, bool> &config, OperatorConfig &poc, std::string configName)
236 {
237 auto it = poc.boolValue.find(configName);
238 if (it != poc.boolValue.end()) {
239 config[slotId] = it->second;
240 } else {
241 TELEPHONY_LOGE("do't find operator config %{public}s", configName.c_str());
242 }
243 }
244
ResetImsSwitch(int32_t slotId)245 void CellularCallConfig::ResetImsSwitch(int32_t slotId)
246 {
247 bool hasSimCard = false;
248 CoreManagerInner::GetInstance().HasSimCard(slotId, hasSimCard);
249 if (!hasSimCard) {
250 TELEPHONY_LOGE("return due to no sim card");
251 return;
252 }
253 std::u16string iccId;
254 CoreManagerInner::GetInstance().GetSimIccId(slotId, iccId);
255 if (IsSimChanged(slotId, Str16ToStr8(iccId)) && forceVolteSwitchOn_[slotId]) {
256 int32_t ret = CoreManagerInner::GetInstance().SaveImsSwitch(
257 slotId, BooleanToImsSwitchValue(imsSwitchOnByDefault_[slotId]));
258 if (ret != TELEPHONY_SUCCESS) {
259 TELEPHONY_LOGE("SaveImsSwitch failed");
260 }
261 }
262 }
263
UpdateImsCapabilities(int32_t slotId,bool needUpdateUtCapability)264 void CellularCallConfig::UpdateImsCapabilities(int32_t slotId, bool needUpdateUtCapability)
265 {
266 bool isGbaValid = IsGbaValid(slotId);
267 ImsCapabilityList imsCapabilityList;
268
269 UpdateImsVoiceCapabilities(slotId, isGbaValid, imsCapabilityList);
270 if (needUpdateUtCapability) {
271 UpdateImsUtCapabilities(slotId, isGbaValid, imsCapabilityList);
272 }
273 configRequest_.UpdateImsCapabilities(slotId, imsCapabilityList);
274 configRequest_.SetImsSwitchStatusRequest(slotId, IsNeedTurnOnIms(imsCapabilityList));
275 }
276
IsGbaValid(int32_t slotId)277 bool CellularCallConfig::IsGbaValid(int32_t slotId)
278 {
279 if (imsGbaRequired_[slotId]) {
280 std::u16string simist = CoreManagerInner::GetInstance().GetSimIst(slotId);
281 std::string simistStr = Str16ToStr8(simist);
282 // If carrier requires that IMS is only available if GBA capable SIM is used,
283 // then this function checks GBA bit in EF IST.
284 // Format of EF IST is defined in 3GPP TS 31.103 (Section 4.2.7).
285 if (!simistStr.empty() && simistStr.length() > 1) {
286 bool result = (IMS_GBA_BIT & simistStr.at(1)) != 0;
287 return result;
288 }
289 }
290 return true;
291 }
292
UpdateImsVoiceCapabilities(int32_t slotId,bool isGbaValid,ImsCapabilityList & imsCapabilityList)293 void CellularCallConfig::UpdateImsVoiceCapabilities(
294 int32_t slotId, bool isGbaValid, ImsCapabilityList &imsCapabilityList)
295 {
296 ImsCapability volteCapability;
297 volteCapability.imsCapabilityType = ImsCapabilityType::CAPABILITY_TYPE_VOICE;
298 volteCapability.imsRadioTech = ImsRegTech::IMS_REG_TECH_LTE;
299 volteCapability.enable =
300 volteSupported_[slotId] && isGbaValid && GetSwitchStatus(slotId) && IsVolteProvisioned(slotId);
301 imsCapabilityList.imsCapabilities.push_back(volteCapability);
302
303 ImsCapability vonrCapability;
304 vonrCapability.imsCapabilityType = ImsCapabilityType::CAPABILITY_TYPE_VOICE;
305 vonrCapability.imsRadioTech = ImsRegTech::IMS_REG_TECH_NR;
306 vonrCapability.enable = volteCapability.enable && IsVonrSupported(slotId, isGbaValid);
307 imsCapabilityList.imsCapabilities.push_back(vonrCapability);
308 }
309
UpdateImsUtCapabilities(int32_t slotId,bool isGbaValid,ImsCapabilityList & imsCapabilityList)310 void CellularCallConfig::UpdateImsUtCapabilities(int32_t slotId, bool isGbaValid, ImsCapabilityList &imsCapabilityList)
311 {
312 ImsCapability utCapability;
313 utCapability.imsCapabilityType = ImsCapabilityType::CAPABILITY_TYPE_UT;
314 utCapability.imsRadioTech = ImsRegTech::IMS_REG_TECH_LTE;
315 utCapability.enable = ssOverUtSupported_[slotId] && isGbaValid && IsUtProvisioned(slotId);
316 imsCapabilityList.imsCapabilities.push_back(utCapability);
317 }
318
IsVolteProvisioned(int32_t slotId)319 bool CellularCallConfig::IsVolteProvisioned(int32_t slotId)
320 {
321 if (volteProvisioningSupported_[slotId]) {
322 int32_t volteFeatureValue;
323 int32_t result = configRequest_.GetImsFeatureValueRequest(FeatureType::TYPE_VOICE_OVER_LTE, volteFeatureValue);
324 if (result != TELEPHONY_SUCCESS) {
325 TELEPHONY_LOGE("get volte feature value failed");
326 return false;
327 }
328 return volteFeatureValue == ImsFeatureIntResult::IMS_FEATURE_INT_VALUE_ENABLED;
329 }
330 return true;
331 }
332
IsVonrSupported(int32_t slotId,bool isGbaValid)333 bool CellularCallConfig::IsVonrSupported(int32_t slotId, bool isGbaValid)
334 {
335 if (std::find(nrModeSupportedList_[slotId].begin(), nrModeSupportedList_[slotId].end(),
336 CARRIER_NR_AVAILABILITY_SA) == nrModeSupportedList_[slotId].end()) {
337 return false;
338 }
339 return isGbaValid;
340 }
341
IsUtProvisioned(int32_t slotId)342 bool CellularCallConfig::IsUtProvisioned(int32_t slotId)
343 {
344 if (utProvisioningSupported_[slotId]) {
345 int32_t utFeatureValue;
346 int32_t result = configRequest_.GetImsFeatureValueRequest(FeatureType::TYPE_SS_OVER_UT, utFeatureValue);
347 if (result != TELEPHONY_SUCCESS) {
348 TELEPHONY_LOGE("get ut feature value failed");
349 return false;
350 }
351 return utFeatureValue == ImsFeatureIntResult::IMS_FEATURE_INT_VALUE_ENABLED;
352 }
353 return true;
354 }
355
BuildEmergencyCall(int32_t slotId,const EmergencyInfo & from)356 EmergencyCall CellularCallConfig::BuildEmergencyCall(int32_t slotId, const EmergencyInfo &from)
357 {
358 EmergencyCall to = {};
359 to.eccNum = from.eccNum;
360 to.eccType = EccType(from.category);
361 to.simpresent = SimpresentType(from.simpresent);
362 to.mcc = from.mcc;
363 to.abnormalService = AbnormalServiceType(from.abnormalService);
364 return to;
365 }
366
IsNeedTurnOnIms(const ImsCapabilityList & imsCapabilityList)367 bool CellularCallConfig::IsNeedTurnOnIms(const ImsCapabilityList &imsCapabilityList)
368 {
369 for (auto imsCapabilitie : imsCapabilityList.imsCapabilities) {
370 if (imsCapabilitie.imsCapabilityType == ImsCapabilityType::CAPABILITY_TYPE_VOICE
371 || imsCapabilitie.imsCapabilityType == ImsCapabilityType::CAPABILITY_TYPE_VIDEO) {
372 if (imsCapabilitie.enable) {
373 return true;
374 }
375 }
376 }
377 return false;
378 }
379
IsSimChanged(int32_t slotId,std::string iccid)380 bool CellularCallConfig::IsSimChanged(int32_t slotId, std::string iccid)
381 {
382 const int32_t sysparaSize = SYSTEM_PARAMETER_LENGTH;
383 char lastIccid[sysparaSize] = { 0 };
384 std::string key = LAST_ICCID_KEY + std::to_string(slotId);
385 GetParameter(key.c_str(), "", lastIccid, sysparaSize);
386
387 if (iccid.compare(lastIccid) != 0) {
388 SetParameter(key.c_str(), iccid.c_str());
389 return true;
390 }
391 return false;
392 }
393
ChangeImsSwitchWithOperatorConfig(int32_t slotId,bool active)394 bool CellularCallConfig::ChangeImsSwitchWithOperatorConfig(int32_t slotId, bool active)
395 {
396 auto itorHide = hideImsSwitch_.find(slotId);
397 if (itorHide != hideImsSwitch_.end()) {
398 if (itorHide->second) {
399 auto itorSwitch = imsSwitchOnByDefault_.find(slotId);
400 if (itorSwitch != imsSwitchOnByDefault_.end()) {
401 active = imsSwitchOnByDefault_[slotId];
402 return active;
403 }
404 }
405 }
406 TELEPHONY_LOGE("do not find hideImsSwitch or imsSwitchOnByDefault config");
407 return active;
408 }
409
SaveImsSwitch(int32_t slotId,int32_t imsSwitchValue)410 int32_t CellularCallConfig::SaveImsSwitch(int32_t slotId, int32_t imsSwitchValue)
411 {
412 int32_t lastImsSwitchValue;
413 int32_t queryRet = CoreManagerInner::GetInstance().QueryImsSwitch(slotId, lastImsSwitchValue);
414 if (queryRet != TELEPHONY_SUCCESS) {
415 TELEPHONY_LOGE("query ims switch failed");
416 return SAVE_IMS_SWITCH_FAILED;
417 }
418
419 if (imsSwitchValue == lastImsSwitchValue) {
420 TELEPHONY_LOGI("ims switch status do not change, imsSwitchValue: %{public}d", imsSwitchValue);
421 return SAVE_IMS_SWITCH_SUCCESS_NOT_CHANGED;
422 }
423 int32_t saveRet = CoreManagerInner::GetInstance().SaveImsSwitch(slotId, imsSwitchValue);
424 if (saveRet != TELEPHONY_SUCCESS) {
425 TELEPHONY_LOGE("save ims switch failed!");
426 return SAVE_IMS_SWITCH_FAILED;
427 }
428 return SAVE_IMS_SWITCH_SUCCESS_CHANGED;
429 }
430
HandleSetLteImsSwitchResult(int32_t slotId,HRilErrType result)431 void CellularCallConfig::HandleSetLteImsSwitchResult(int32_t slotId, HRilErrType result)
432 {
433 TELEPHONY_LOGI("CellularCallConfig::HandleSetLteImsSwitchResult entry, slotId: %{public}d", slotId);
434 if (result != HRilErrType::NONE) {
435 TELEPHONY_LOGE("HandleSetLteImsSwitchResult set ims switch to modem failed!");
436 // need to reset the Ims Switch parameter and notify APP to update UI.
437 }
438 }
439
GetDomainPreferenceModeResponse(int32_t slotId,int32_t mode)440 void CellularCallConfig::GetDomainPreferenceModeResponse(int32_t slotId, int32_t mode)
441 {
442 modeMap_[slotId] = mode;
443 }
444
GetImsSwitchStatusResponse(int32_t slotId,int32_t active)445 void CellularCallConfig::GetImsSwitchStatusResponse(int32_t slotId, int32_t active) {}
446
GetPreferenceMode(int32_t slotId) const447 int32_t CellularCallConfig::GetPreferenceMode(int32_t slotId) const
448 {
449 return modeMap_[slotId];
450 }
451
GetSwitchStatus(int32_t slotId) const452 int32_t CellularCallConfig::GetSwitchStatus(int32_t slotId) const
453 {
454 TELEPHONY_LOGI("CellularCallConfig::GetSwitchStatus entry, slotId: %{public}d", slotId);
455 int32_t imsSwitchStatus;
456 int32_t ret = CoreManagerInner::GetInstance().QueryImsSwitch(slotId, imsSwitchStatus);
457 if (ret != TELEPHONY_SUCCESS) {
458 TELEPHONY_LOGE("get ims switch failed");
459 return imsSwitchOnByDefault_[slotId] ? IMS_SWITCH_STATUS_ON : IMS_SWITCH_STATUS_OFF;
460 }
461 TELEPHONY_LOGI("imsSwitchStatus : %{public}d", imsSwitchStatus);
462 return imsSwitchStatus;
463 }
464
SetImsConfig(ImsConfigItem item,const std::string & value)465 int32_t CellularCallConfig::SetImsConfig(ImsConfigItem item, const std::string &value)
466 {
467 return configRequest_.SetImsConfigRequest(item, value);
468 }
469
SetImsConfig(ImsConfigItem item,int32_t value)470 int32_t CellularCallConfig::SetImsConfig(ImsConfigItem item, int32_t value)
471 {
472 return configRequest_.SetImsConfigRequest(item, value);
473 }
474
GetImsConfig(ImsConfigItem item)475 int32_t CellularCallConfig::GetImsConfig(ImsConfigItem item)
476 {
477 return configRequest_.GetImsConfigRequest(item);
478 }
479
SetImsFeatureValue(FeatureType type,int32_t value)480 int32_t CellularCallConfig::SetImsFeatureValue(FeatureType type, int32_t value)
481 {
482 return configRequest_.SetImsFeatureValueRequest(type, value);
483 }
484
GetImsFeatureValue(FeatureType type)485 int32_t CellularCallConfig::GetImsFeatureValue(FeatureType type)
486 {
487 int32_t imsFeatureValue;
488 int32_t ret = configRequest_.GetImsFeatureValueRequest(type, imsFeatureValue);
489 GetImsFeatureValueResponse response;
490 response.result = ret;
491 response.value = imsFeatureValue;
492 DelayedSingleton<CellularCallRegister>::GetInstance()->ReportGetImsFeatureResult(response);
493 return ret;
494 }
495
CtrlCamera(const std::u16string & cameraId,int32_t callingUid,int32_t callingPid)496 int32_t CellularCallConfig::CtrlCamera(const std::u16string &cameraId, int32_t callingUid, int32_t callingPid)
497 {
498 return configRequest_.CtrlCameraRequest(cameraId, callingUid, callingPid);
499 }
500
SetPreviewWindow(int32_t x,int32_t y,int32_t z,int32_t width,int32_t height)501 int32_t CellularCallConfig::SetPreviewWindow(int32_t x, int32_t y, int32_t z, int32_t width, int32_t height)
502 {
503 return configRequest_.SetPreviewWindowRequest(x, y, z, width, height);
504 }
505
SetDisplayWindow(int32_t x,int32_t y,int32_t z,int32_t width,int32_t height)506 int32_t CellularCallConfig::SetDisplayWindow(int32_t x, int32_t y, int32_t z, int32_t width, int32_t height)
507 {
508 return configRequest_.SetDisplayWindowRequest(x, y, z, width, height);
509 }
510
SetCameraZoom(float zoomRatio)511 int32_t CellularCallConfig::SetCameraZoom(float zoomRatio)
512 {
513 return configRequest_.SetCameraZoomRequest(zoomRatio);
514 }
515
SetPauseImage(const std::u16string & path)516 int32_t CellularCallConfig::SetPauseImage(const std::u16string &path)
517 {
518 return configRequest_.SetPauseImageRequest(path);
519 }
520
SetDeviceDirection(int32_t rotation)521 int32_t CellularCallConfig::SetDeviceDirection(int32_t rotation)
522 {
523 return configRequest_.SetDeviceDirectionRequest(rotation);
524 }
525
SetTempMode(int32_t slotId)526 void CellularCallConfig::SetTempMode(int32_t slotId)
527 {
528 modeMap_[slotId] = modeTempMap_[slotId];
529 }
530
InitModeActive()531 void CellularCallConfig::InitModeActive()
532 {
533 int32_t slotId = DEFAULT_SIM_SLOT_ID;
534 modeMap_[slotId] = DomainPreferenceMode::IMS_PS_VOICE_PREFERRED;
535 eccListRadioMap_.clear();
536 eccList3gppHasSim_.clear();
537 eccList3gppNoSim_.clear();
538 eccListConfigMap_.clear();
539 allEccList_.clear();
540 eccList3gppHasSim_.push_back(BuildDefaultEmergencyCall("112"));
541 eccList3gppHasSim_.push_back(BuildDefaultEmergencyCall("991"));
542 eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("112"));
543 eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("991"));
544 eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("000"));
545 eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("08"));
546 eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("110"));
547 eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("118"));
548 eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("119"));
549 eccList3gppNoSim_.push_back(BuildDefaultEmergencyCall("999"));
550 TELEPHONY_LOGI("InitModeActive finish");
551 }
552
BuildDefaultEmergencyCall(const std::string & number)553 EmergencyCall CellularCallConfig::BuildDefaultEmergencyCall(const std::string &number)
554 {
555 EmergencyCall emergencyCall;
556 emergencyCall.eccNum = number;
557 emergencyCall.eccType = EccType::TYPE_CATEGORY;
558 emergencyCall.simpresent = SimpresentType::TYPE_HAS_CARD;
559 emergencyCall.mcc = "";
560 emergencyCall.abnormalService = AbnormalServiceType::TYPE_ALL;
561 return emergencyCall;
562 }
563
UpdateEccWhenOperatorConfigChange(int32_t slotId,OperatorConfig & opc)564 void CellularCallConfig::UpdateEccWhenOperatorConfigChange(int32_t slotId, OperatorConfig &opc)
565 {
566 eccListConfigMap_[slotId].clear();
567 std::vector<EmergencyCall> configVector;
568 std::string mcc = GetMcc(slotId);
569 if (mcc.empty()) {
570 TELEPHONY_LOGE("MergeEccCallList countryCode is null");
571 return;
572 }
573 std::vector<std::string> callList = opc.stringArrayValue[KEY_EMERGENCY_CALL_STRING_ARRAY];
574 for (auto call : callList) {
575 auto emergencyCall = BuildDefaultEmergencyCall(call);
576 emergencyCall.mcc = mcc;
577 configVector.push_back(emergencyCall);
578 }
579 eccListConfigMap_[slotId] = configVector;
580 TELEPHONY_LOGI("UpdateEccWhenOperatorConfigChange slotId %{public}d config call size %{public}zu success", slotId,
581 callList.size());
582 MergeEccCallList(slotId);
583 SetEmergencyCallList(slotId);
584 }
585
MergeEccCallList(int32_t slotId_)586 void CellularCallConfig::MergeEccCallList(int32_t slotId_)
587 {
588 std::lock_guard<std::mutex> lock(mutex_);
589 allEccList_[slotId_].clear();
590 for (auto ecc : eccListRadioMap_[slotId_]) {
591 allEccList_[slotId_].push_back(ecc);
592 }
593 TELEPHONY_LOGI("MergeEccCallList merge radio slotId %{public}d size %{public}d", slotId_,
594 static_cast<int32_t>(eccListRadioMap_[slotId_].size()));
595 for (auto ecc : eccListConfigMap_[slotId_]) {
596 allEccList_[slotId_].push_back(ecc);
597 }
598 TELEPHONY_LOGI("MergeEccCallList merge config slotId %{public}d size %{public}zu", slotId_,
599 eccListConfigMap_[slotId_].size());
600 SimState simState = SimState::SIM_STATE_UNKNOWN;
601 CoreManagerInner::GetInstance().GetSimState(slotId_, simState);
602 if (simState != SimState::SIM_STATE_NOT_PRESENT) {
603 std::string mcc = GetMcc(slotId_);
604 if (mcc.empty()) {
605 TELEPHONY_LOGE("MergeEccCallList countryCode is null");
606 return;
607 }
608 for (auto ecc : eccList3gppHasSim_) {
609 ecc.mcc = mcc;
610 allEccList_[slotId_].push_back(ecc);
611 }
612 } else {
613 for (auto ecc : eccList3gppNoSim_) {
614 allEccList_[slotId_].push_back(ecc);
615 }
616 }
617 UniqueEccCallList(slotId_);
618 }
619
UniqueEccCallList(int32_t slotId_)620 void CellularCallConfig::UniqueEccCallList(int32_t slotId_)
621 {
622 std::vector<EmergencyCall> uniques;
623 for (auto call : allEccList_[slotId_]) {
624 if (std::find(uniques.begin(), uniques.end(), call) == uniques.end()) {
625 uniques.push_back(call);
626 }
627 }
628 TELEPHONY_LOGI("UniqueEccCallList end slotId %{public}d from size %{public}zu to size %{public}zu", slotId_,
629 allEccList_[slotId_].size(), uniques.size());
630 }
631
GetMcc(int32_t slotId_)632 std::string CellularCallConfig::GetMcc(int32_t slotId_)
633 {
634 std::u16string operatorNumeric;
635 CoreManagerInner::GetInstance().GetSimOperatorNumeric(slotId_, operatorNumeric);
636 std::string imsi = Str16ToStr8(operatorNumeric);
637 int len = static_cast<int>(imsi.length());
638 std::string mcc = imsi;
639 if (len >= MCC_LEN) {
640 mcc = imsi.substr(0, MCC_LEN);
641 }
642 TELEPHONY_LOGI("getMcc slotd %{public}d mcc %{public}s end", slotId_, mcc.c_str());
643 return mcc;
644 }
645
SetEmergencyCallList(int32_t slotId)646 int32_t CellularCallConfig::SetEmergencyCallList(int32_t slotId)
647 {
648 TELEPHONY_LOGI("SetEmergencyCallList start");
649 return SetEmergencyCallList(slotId, allEccList_[slotId]);
650 }
651
SetMute(int32_t slotId,int32_t mute)652 int32_t CellularCallConfig::SetMute(int32_t slotId, int32_t mute)
653 {
654 return configRequest_.SetMuteRequest(slotId, mute);
655 }
656
GetMute(int32_t slotId)657 int32_t CellularCallConfig::GetMute(int32_t slotId)
658 {
659 return configRequest_.GetMuteRequest(slotId);
660 }
661
GetEmergencyCallList(int32_t slotId)662 int32_t CellularCallConfig::GetEmergencyCallList(int32_t slotId)
663 {
664 return configRequest_.GetEmergencyCallListRequest(slotId);
665 }
666
SetEmergencyCallList(int32_t slotId,const std::vector<EmergencyCall> & eccVec)667 int32_t CellularCallConfig::SetEmergencyCallList(int32_t slotId, const std::vector<EmergencyCall> &eccVec)
668 {
669 TELEPHONY_LOGI("SetEmergencyCallList start %{public}d", slotId);
670 std::lock_guard<std::mutex> lock(mutex_);
671 std::vector<EmergencyCall> uniques;
672 for (auto call : eccVec) {
673 if (std::find(eccListRadioMap_[slotId].begin(), eccListRadioMap_[slotId].end(), call) ==
674 eccListRadioMap_[slotId].end()) {
675 uniques.push_back(call);
676 }
677 }
678 TELEPHONY_LOGI("select end slotId %{public}d from size %{public}zu to size %{public}zu", slotId, eccVec.size(),
679 uniques.size());
680 if (uniques.size() <= 0) {
681 TELEPHONY_LOGI("SetEmergencyCallList eccList has exit");
682 return TELEPHONY_ERR_SUCCESS;
683 }
684 TELEPHONY_LOGI("SetEmergencyCallList refresh size %{public}zu", uniques.size());
685 for (auto ecc : uniques) {
686 allEccList_[slotId].push_back(ecc);
687 }
688 return configRequest_.SetEmergencyCallListRequest(slotId, uniques);
689 }
690
IsNeedUpdateEccListWhenSimStateChanged(int32_t slotId)691 bool CellularCallConfig::IsNeedUpdateEccListWhenSimStateChanged(int32_t slotId)
692 {
693 SimState simState = SimState::SIM_STATE_UNKNOWN;
694 CoreManagerInner::GetInstance().GetSimState(slotId, simState);
695 int32_t simStateForEcc;
696 switch (simState) {
697 case SimState::SIM_STATE_READY:
698 case SimState::SIM_STATE_LOADED: {
699 simStateForEcc = SIM_PRESENT;
700 break;
701 }
702 default: {
703 simStateForEcc = SIM_ABSENT;
704 break;
705 }
706 }
707 bool result = (simState_[slotId] != simStateForEcc);
708 simState_[slotId] = simStateForEcc;
709 return result;
710 }
711
UpdateEmergencyCallFromRadio(int32_t slotId,const EmergencyInfoList & eccList)712 void CellularCallConfig::UpdateEmergencyCallFromRadio(int32_t slotId, const EmergencyInfoList &eccList)
713 {
714 TELEPHONY_LOGI("UpdateEmergencyCallFromRadio %{publid}d size %{public}d", slotId, eccList.callSize);
715 eccListRadioMap_[slotId] = std::vector<EmergencyCall>();
716 for (auto ecc : eccList.calls) {
717 TELEPHONY_LOGI("UpdateEmergencyCallFromRadio , data: eccNum %{public}s mcc %{public}s", ecc.eccNum.c_str(),
718 ecc.mcc.c_str());
719 eccListRadioMap_[slotId].push_back(BuildEmergencyCall(slotId, ecc));
720 }
721 MergeEccCallList(slotId);
722 }
723
GetEccCallList(int32_t slotId)724 std::vector<EmergencyCall> CellularCallConfig::GetEccCallList(int32_t slotId)
725 {
726 TELEPHONY_LOGI("GetEccCallList start %{public}d", slotId);
727 std::lock_guard<std::mutex> lock(mutex_);
728 TELEPHONY_LOGI("GetEccCallList size %{public}zu", allEccList_[slotId].size());
729 for (auto ecc : allEccList_[slotId]) {
730 TELEPHONY_LOGI("GetEccCallList, data: eccNum %{public}s mcc %{public}s", ecc.eccNum.c_str(), ecc.mcc.c_str());
731 }
732 return allEccList_[slotId];
733 }
734
BooleanToImsSwitchValue(bool value)735 int32_t CellularCallConfig::BooleanToImsSwitchValue(bool value)
736 {
737 return value ? IMS_SWITCH_VALUE_ENABLED : IMS_SWITCH_VALUE_DISABLED;
738 }
739
GetImsSwitchOnByDefaultConfig(int32_t slotId)740 bool CellularCallConfig::GetImsSwitchOnByDefaultConfig(int32_t slotId)
741 {
742 if (!IsValidSlotId(slotId)) {
743 TELEPHONY_LOGE("invalid slot id");
744 return true;
745 }
746 return imsSwitchOnByDefault_[slotId];
747 }
748
GethideImsSwitchConfig(int32_t slotId)749 bool CellularCallConfig::GethideImsSwitchConfig(int32_t slotId)
750 {
751 if (!IsValidSlotId(slotId)) {
752 TELEPHONY_LOGE("invalid slot id");
753 return false;
754 }
755 return hideImsSwitch_[slotId];
756 }
757
GetvolteSupportedConfig(int32_t slotId)758 bool CellularCallConfig::GetvolteSupportedConfig(int32_t slotId)
759 {
760 if (!IsValidSlotId(slotId)) {
761 TELEPHONY_LOGE("invalid slot id");
762 return false;
763 }
764 return volteSupported_[slotId];
765 }
766
GetNrModeSupportedListConfig(int32_t slotId)767 std::vector<int32_t> CellularCallConfig::GetNrModeSupportedListConfig(int32_t slotId)
768 {
769 if (!IsValidSlotId(slotId)) {
770 TELEPHONY_LOGE("invalid slot id");
771 return std::vector<int32_t> { CARRIER_NR_AVAILABILITY_NSA, CARRIER_NR_AVAILABILITY_SA };
772 }
773 return nrModeSupportedList_[slotId];
774 }
775
GetVolteProvisioningSupportedConfig(int32_t slotId)776 bool CellularCallConfig::GetVolteProvisioningSupportedConfig(int32_t slotId)
777 {
778 if (!IsValidSlotId(slotId)) {
779 TELEPHONY_LOGE("invalid slot id");
780 return false;
781 }
782 return volteProvisioningSupported_[slotId];
783 }
784
GetSsOverUtSupportedConfig(int32_t slotId)785 bool CellularCallConfig::GetSsOverUtSupportedConfig(int32_t slotId)
786 {
787 if (!IsValidSlotId(slotId)) {
788 TELEPHONY_LOGE("invalid slot id");
789 return false;
790 }
791 return ssOverUtSupported_[slotId];
792 }
793
GetImsGbaRequiredConfig(int32_t slotId)794 bool CellularCallConfig::GetImsGbaRequiredConfig(int32_t slotId)
795 {
796 if (!IsValidSlotId(slotId)) {
797 TELEPHONY_LOGE("invalid slot id");
798 return false;
799 }
800 return imsGbaRequired_[slotId];
801 }
802
GetUtProvisioningSupportedConfig(int32_t slotId)803 bool CellularCallConfig::GetUtProvisioningSupportedConfig(int32_t slotId)
804 {
805 if (!IsValidSlotId(slotId)) {
806 TELEPHONY_LOGE("invalid slot id");
807 return false;
808 }
809 return utProvisioningSupported_[slotId];
810 }
811
GetImsPreferForEmergencyConfig(int32_t slotId)812 bool CellularCallConfig::GetImsPreferForEmergencyConfig(int32_t slotId)
813 {
814 if (!IsValidSlotId(slotId)) {
815 TELEPHONY_LOGE("invalid slot id");
816 return true;
817 }
818 return imsPreferForEmergency_[slotId];
819 }
820
GetCallWaitingServiceClassConfig(int32_t slotId)821 std::int32_t CellularCallConfig::GetCallWaitingServiceClassConfig(int32_t slotId)
822 {
823 if (!IsValidSlotId(slotId)) {
824 TELEPHONY_LOGE("invalid slot id");
825 return 1;
826 }
827 return callWaitingServiceClass_[slotId];
828 }
829
GetImsCallDisconnectResoninfoMappingConfig(int32_t slotId)830 std::vector<std::string> CellularCallConfig::GetImsCallDisconnectResoninfoMappingConfig(int32_t slotId)
831 {
832 if (!IsValidSlotId(slotId)) {
833 TELEPHONY_LOGE("invalid slot id");
834 return std::vector<std::string> {};
835 }
836 return imsCallDisconnectResoninfoMapping_[slotId];
837 }
838
GetForceVolteSwitchOnConfig(int32_t slotId)839 bool CellularCallConfig::GetForceVolteSwitchOnConfig(int32_t slotId)
840 {
841 if (!IsValidSlotId(slotId)) {
842 TELEPHONY_LOGE("invalid slot id");
843 return false;
844 }
845 return forceVolteSwitchOn_[slotId];
846 }
847
IsValidSlotId(int32_t slotId)848 bool CellularCallConfig::IsValidSlotId(int32_t slotId)
849 {
850 int32_t count = SIM_SLOT_COUNT;
851 if ((slotId >= DEFAULT_SIM_SLOT_ID) && (slotId < count)) {
852 return true;
853 }
854
855 TELEPHONY_LOGE("SlotId is InValid = %{public}d", slotId);
856 return false;
857 }
858 } // namespace Telephony
859 } // namespace OHOS
860