• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "cellular_call_config.h"
17 
18 #include "cellular_call_data_struct.h"
19 #include "cellular_call_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