• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 #include "operator_config_cache.h"
16 
17 #include <fstream>
18 #include <openssl/sha.h>
19 #include <string_ex.h>
20 #include <telephony_types.h>
21 
22 #include "cJSON.h"
23 #include "common_event_manager.h"
24 #include "common_event_support.h"
25 #include "core_manager_inner.h"
26 #include "pdp_profile_rdb_helper.h"
27 #include "radio_event.h"
28 #include "parameters.h"
29 
30 namespace OHOS {
31 namespace Telephony {
OperatorConfigCache(std::weak_ptr<SimFileManager> simFileManager,std::shared_ptr<SimStateManager> simStateManager,int32_t slotId)32 OperatorConfigCache::OperatorConfigCache(
33     std::weak_ptr<SimFileManager> simFileManager, std::shared_ptr<SimStateManager> simStateManager, int32_t slotId)
34     : TelEventHandler("OperatorConfigCache"), simFileManager_(simFileManager), simStateManager_(simStateManager),
35       slotId_(slotId)
36 {
37     TELEPHONY_LOGI("OperatorConfigCache create");
38 }
39 
ClearAllCache(int32_t slotId)40 void OperatorConfigCache::ClearAllCache(int32_t slotId)
41 {
42     std::unique_lock<std::mutex> lock(mutex_);
43     ClearOperatorValue(slotId);
44     ClearMemoryCache(slotId);
45     OperatorFileParser::ClearFilesCache();
46     lock.unlock();
47 }
48 
ClearMemoryAndOpkey(int32_t slotId)49 void OperatorConfigCache::ClearMemoryAndOpkey(int32_t slotId)
50 {
51     std::unique_lock<std::mutex> lock(mutex_);
52     ClearOperatorValue(slotId);
53     ClearMemoryCache(slotId);
54     lock.unlock();
55 }
56 
ClearOperatorValue(int32_t slotId)57 void OperatorConfigCache::ClearOperatorValue(int32_t slotId)
58 {
59     auto simFileManager = simFileManager_.lock();
60     if (simFileManager == nullptr) {
61         TELEPHONY_LOGE("simFileManager is nullptr");
62         return;
63     }
64     std::string key;
65     std::string initialOpkey = INITIAL_OPKEY;
66     SetParameter(key.append(OPKEY_PROP_PREFIX).append(std::to_string(slotId)).c_str(), initialOpkey.c_str());
67     simFileManager->SetOpKey("");
68     simFileManager->SetOpName("");
69     simFileManager->SetOpKeyExt("");
70 }
71 
ClearMemoryCache(int32_t slotId)72 void OperatorConfigCache::ClearMemoryCache(int32_t slotId)
73 {
74     opc_.stringValue.clear();
75     opc_.stringArrayValue.clear();
76     opc_.intValue.clear();
77     opc_.intArrayValue.clear();
78     opc_.longValue.clear();
79     opc_.longArrayValue.clear();
80     opc_.boolValue.clear();
81     opc_.configValue.clear();
82 }
83 
UpdateCurrentOpc(int32_t slotId,OperatorConfig & poc)84 void OperatorConfigCache::UpdateCurrentOpc(int32_t slotId, OperatorConfig &poc)
85 {
86     bool isUseCloudImsNV = system::GetBoolParameter(KEY_CONST_TELEPHONY_IS_USE_CLOUD_IMS_NV, true);
87     TELEPHONY_LOGI("[slot%{public}d], isUseCloudImsNV = %{public}d", slotId, isUseCloudImsNV);
88     if (isUseCloudImsNV && isUpdateImsCapFromChipDone_) {
89         UpdatevolteCap(slotId, poc);
90     }
91     std::unique_lock<std::mutex> lock(mutex_);
92     ClearMemoryCache(slotId);
93     CopyOperatorConfig(poc, opc_);
94     lock.unlock();
95 }
96 
UpdateOpcBoolValue(OperatorConfig & opc,const std::string & key,const bool value)97 void OperatorConfigCache::UpdateOpcBoolValue(OperatorConfig &opc, const std::string &key, const bool value)
98 {
99     std::map<std::string, bool>::iterator it = opc.boolValue.find(key);
100     bool result;
101     if (it != opc.boolValue.end()) {
102         result = it->second && value;
103         it->second = result;
104     } else {
105         TELEPHONY_LOGI("Not find in opc");
106         result = value;
107         opc.boolValue.emplace(key, value);
108     }
109 
110     std::u16string sResult = result ? u"true" : u"false";
111     opc.configValue[Str8ToStr16(key)] = sResult;
112 }
113 
UpdatevolteCap(int32_t slotId,OperatorConfig & opc)114 void OperatorConfigCache::UpdatevolteCap(int32_t slotId, OperatorConfig &opc)
115 {
116     std::string volteCapKey = KEY_PERSIST_TELEPHONY_VOLTE_CAP_IN_CHIP + std::to_string(slotId);
117     int32_t volteCapInChip = GetIntParameter(volteCapKey.c_str(), -1);
118     TELEPHONY_LOGI("[slot%{public}d] volteCapInChip = %{public}d", slotId, volteCapInChip);
119 
120     std::unique_lock<std::mutex> lock(mutex_);
121     switch (volteCapInChip) {
122         case IMS_SWITCH_OFF:
123             UpdateOpcBoolValue(opc, "volte_supported_bool", false);
124             break;
125         case IMS_SWITCH_ON:
126             UpdateOpcBoolValue(opc, "volte_supported_bool", true);
127             break;
128         case IMS_SWITCH_DEFAULT:
129             UpdateOpcBoolValue(opc, "volte_supported_bool", true);
130             opc.boolValue["hide_ims_switch_bool"] = false;
131             opc.boolValue["ims_switch_on_by_default_bool"] = false;
132             opc.configValue[u"hide_ims_switch_bool"] = u"false";
133             opc.configValue[u"ims_switch_on_by_default_bool"] = u"false";
134             break;
135         default:
136             TELEPHONY_LOGE("Invalid volte para!");
137             break;
138     }
139     lock.unlock();
140 }
141 
LoadOperatorConfigFile(int32_t slotId,OperatorConfig & poc)142 int32_t OperatorConfigCache::LoadOperatorConfigFile(int32_t slotId, OperatorConfig &poc)
143 {
144     auto simFileManager = simFileManager_.lock();
145     if (simFileManager == nullptr) {
146         return TELEPHONY_ERR_LOCAL_PTR_NULL;
147     }
148     std::string iccid = Str16ToStr8(simFileManager->GetSimIccId());
149     std::string opkey = GetOpKey(slotId);
150     std::string filename = EncryptIccId(iccid + opkey) + ".json";
151     if (opkey == std::string(INITIAL_OPKEY)) {
152         TELEPHONY_LOGI("load default operator config, slotId = %{public}d", slotId);
153         filename = DEFAULT_OPERATOR_CONFIG;
154     }
155     if (iccid != "" && iccid != iccidCache_) {
156         isUpdateImsCapFromChipDone_ = false;
157     }
158     isLoadingConfig_ = true;
159     TELEPHONY_LOGI("LoadOperatorConfig slotId = %{public}d, opkey = %{public}s", slotId, opkey.data());
160     cJSON *root = nullptr;
161     std::string filePath = parser_.GetOperatorConfigFilePath(filename);
162     if (parser_.ParseOperatorConfigFromFile(poc, filePath, root)) {
163         TELEPHONY_LOGI("load from file success opc size %{public}zu, slotId = %{public}d",
164             poc.configValue.size(), slotId);
165         if (poc.configValue.size() > 0) {
166             UpdateCurrentOpc(slotId, poc);
167             isLoadingConfig_ = false;
168             root = nullptr;
169             return TELEPHONY_ERR_SUCCESS;
170         }
171     }
172     root = cJSON_CreateObject();
173     if (parser_.ParseFromCustomSystem(slotId, poc, root)) {
174         TELEPHONY_LOGI("load from custom system success, slotId = %{public}d", slotId);
175         parser_.WriteOperatorConfigJson(filePath.c_str(), root);
176         if (poc.configValue.size() > 0) {
177             UpdateCurrentOpc(slotId, poc);
178             isLoadingConfig_ = false;
179             if (root != nullptr) {
180                 cJSON_Delete(root);
181                 root = nullptr;
182             }
183             return TELEPHONY_ERR_SUCCESS;
184         }
185     }
186     isLoadingConfig_ = false;
187     if (root != nullptr) {
188         cJSON_Delete(root);
189         root = nullptr;
190     }
191     return CORE_ERR_OPERATOR_CONF_NOT_EXIT;
192 }
193 
LoadOperatorConfig(int32_t slotId,OperatorConfig & poc,int32_t state)194 int32_t OperatorConfigCache::LoadOperatorConfig(int32_t slotId, OperatorConfig &poc, int32_t state)
195 {
196     UpdateIccidCache(state);
197     if (LoadOperatorConfigFile(slotId, poc) == TELEPHONY_ERR_SUCCESS) {
198         AnnounceOperatorConfigChanged(slotId, state);
199         return TELEPHONY_ERR_SUCCESS;
200     }
201     return CORE_ERR_OPERATOR_CONF_NOT_EXIT;
202 }
203 
GetOperatorConfigs(int32_t slotId,OperatorConfig & poc)204 int32_t OperatorConfigCache::GetOperatorConfigs(int32_t slotId, OperatorConfig &poc)
205 {
206     std::unique_lock<std::mutex> lock(mutex_);
207     if (opc_.configValue.size() > 0) {
208         TELEPHONY_LOGD("get from memory");
209         CopyOperatorConfig(opc_, poc);
210         lock.unlock();
211         return TELEPHONY_ERR_SUCCESS;
212     }
213     lock.unlock();
214     TELEPHONY_LOGI("reload operator config, slotId = %{public}d", slotId);
215     return LoadOperatorConfigFile(slotId, poc);
216 }
217 
UpdateOperatorConfigs(int32_t slotId)218 int32_t OperatorConfigCache::UpdateOperatorConfigs(int32_t slotId)
219 {
220     std::unique_lock<std::mutex> lock(mutex_);
221     ClearMemoryCache(slotId);
222     lock.unlock();
223     if (slotId == 0) {
224         TELEPHONY_LOGD("UpdateOperatorConfigs ClearFilesCache");
225         OperatorFileParser::ClearFilesCache();
226     }
227     OperatorConfig opc;
228     int32_t ret = LoadOperatorConfig(slotId_, opc, STATE_PARA_UPDATE);
229     return ret;
230 }
231 
CopyOperatorConfig(const OperatorConfig & from,OperatorConfig & to)232 void OperatorConfigCache::CopyOperatorConfig(const OperatorConfig &from, OperatorConfig &to)
233 {
234     for (const auto &it : from.configValue) {
235         to.configValue[it.first] = it.second;
236     }
237     for (const auto &it : from.boolValue) {
238         to.boolValue[it.first] = it.second;
239     }
240     for (const auto &it : from.intValue) {
241         to.intValue[it.first] = it.second;
242     }
243     for (const auto &it : from.longValue) {
244         to.longValue[it.first] = it.second;
245     }
246     for (const auto &it : from.stringValue) {
247         to.stringValue[it.first] = it.second;
248     }
249     for (const auto &it : from.intArrayValue) {
250         to.intArrayValue[it.first] = std::vector<int32_t>(it.second);
251     }
252     for (const auto &it : from.longArrayValue) {
253         to.longArrayValue[it.first] = std::vector<int64_t>(it.second);
254     }
255     for (const auto &it : from.stringArrayValue) {
256         to.stringArrayValue[it.first] = std::vector<std::string>(it.second);
257     }
258 }
259 
GetOpKey(int32_t slotId)260 std::string OperatorConfigCache::GetOpKey(int32_t slotId)
261 {
262     char simOpKey[SYSPARA_SIZE] = { 0 };
263     std::string key;
264     GetParameter(key.append(OPKEY_PROP_PREFIX).append(std::to_string(slotId)).c_str(), DEFAULT_OPERATOR_KEY,
265         simOpKey, SYSPARA_SIZE);
266     key.shrink_to_fit();
267     return simOpKey;
268 }
269 
EncryptIccId(const std::string iccid)270 std::string OperatorConfigCache::EncryptIccId(const std::string iccid)
271 {
272     unsigned char hash[SHA256_DIGEST_LENGTH];
273     SHA256_CTX sha256;
274     SHA256_Init(&sha256);
275     SHA256_Update(&sha256, iccid.c_str(), iccid.size());
276     SHA256_Final(hash, &sha256);
277     std::string encryptIccId = SIMUtils::BytesConvertToHexString(hash, SHA256_DIGEST_LENGTH);
278     return encryptIccId;
279 }
280 
RegisterForIccChange()281 bool OperatorConfigCache::RegisterForIccChange()
282 {
283     auto simFileManager = simFileManager_.lock();
284     if (simFileManager == nullptr) {
285         TELEPHONY_LOGE("can not get SimFileManager");
286         return false;
287     }
288     simFileManager->RegisterCoreNotify(shared_from_this(), RadioEvent::RADIO_SIM_STATE_CHANGE);
289     return true;
290 }
291 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)292 void OperatorConfigCache::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
293 {
294     if (event == nullptr) {
295         TELEPHONY_LOGE("start ProcessEvent but event is null!");
296         return;
297     }
298     SimState simState = SimState::SIM_STATE_UNKNOWN;
299     GetSimState(slotId_, simState);
300     if (event->GetInnerEventId() == RadioEvent::RADIO_SIM_STATE_CHANGE) {
301         TELEPHONY_LOGI("Sim state change, slotId = %{public}d, simstate = %{public}d",
302             slotId_, static_cast<int>(simState));
303         if (simState == SimState::SIM_STATE_NOT_PRESENT || simState == SimState::SIM_STATE_LOCKED ||
304             simState == SimState::SIM_STATE_UNKNOWN) {
305             std::unique_lock<std::mutex> lock(mutex_);
306             ClearOperatorValue(slotId_);
307             modemSimMatchedOpNameCache_ = "";
308             iccidCache_ = "";
309             isUpdateImsCapFromChipDone_ = false;
310             lock.unlock();
311             OperatorConfig opc;
312             LoadOperatorConfig(slotId_, opc, STATE_PARA_CLEAR);
313         }
314     }
315 }
316 
UnRegisterForIccChange()317 bool OperatorConfigCache::UnRegisterForIccChange()
318 {
319     auto simFileManager = simFileManager_.lock();
320     if (simFileManager == nullptr) {
321         TELEPHONY_LOGE("can not get SimFileManager");
322         return false;
323     }
324     simFileManager->UnRegisterCoreNotify(shared_from_this(), RadioEvent::RADIO_SIM_STATE_CHANGE);
325     return true;
326 }
327 
SendSimMatchedOperatorInfo(int32_t slotId,int32_t state)328 void OperatorConfigCache::SendSimMatchedOperatorInfo(int32_t slotId, int32_t state)
329 {
330     auto simFileManager = simFileManager_.lock();
331     if (simFileManager == nullptr) {
332         TELEPHONY_LOGE("can not get SimFileManager");
333         return;
334     }
335     std::string operName = Str16ToStr8(simFileManager->GetOpName());
336     std::string operKey = Str16ToStr8(simFileManager->GetOpKey());
337     std::string iccid = Str16ToStr8(simFileManager->GetSimIccId());
338     if (operKey == "") {
339         operName = "NULL";
340     } else {
341         if (modemSimMatchedOpNameCache_ == "" || (iccid != iccidCache_)) {
342             modemSimMatchedOpNameCache_ = operName;
343             if (iccid != iccidCache_) {
344                 iccidCache_ = iccid;
345             }
346         } else {
347             operName = modemSimMatchedOpNameCache_;
348         }
349     }
350     if (slotId != slotId_) {
351         TELEPHONY_LOGE("is not current slotId, current slotId %{public}d", slotId_);
352         return;
353     }
354     if (simStateManager_ == nullptr) {
355         TELEPHONY_LOGE("simStateManager is nullptr, slotId %{public}d", slotId_);
356         return;
357     }
358     int32_t response = simStateManager_->SendSimMatchedOperatorInfo(slotId, state, operName, operKey);
359     TELEPHONY_LOGI("slotId[%{public}d], opkey[%{public}s],opname[%{public}s], response = %{public}d",
360         slotId, operKey.data(), operName.data(), response);
361 }
362 
notifyInitApnConfigs(int32_t slotId)363 void OperatorConfigCache::notifyInitApnConfigs(int32_t slotId)
364 {
365     auto helper = PdpProfileRdbHelper::GetInstance();
366     if (helper == nullptr) {
367         TELEPHONY_LOGE("get PdpProfileRdbHelper Failed.");
368         return;
369     }
370     TELEPHONY_LOGI("notifyInitApnConfigs end");
371     helper->notifyInitApnConfigs(slotId);
372 }
373 
AnnounceOperatorConfigChanged(int32_t slotId,int32_t state)374 bool OperatorConfigCache::AnnounceOperatorConfigChanged(int32_t slotId, int32_t state)
375 {
376     SimState simState = SimState::SIM_STATE_UNKNOWN;
377     GetSimState(slotId, simState);
378     bool isOpkeyDbError = CoreManagerInner::GetInstance().IsDataShareError();
379     TELEPHONY_LOGI("isOpkeyDbError = %{public}d, state = %{public}d",
380         isOpkeyDbError, state);
381     std::string opkey = GetOpKey(slotId);
382     notifyInitApnConfigs(slotId);
383     SendSimMatchedOperatorInfo(slotId, state);
384     if ((opkey != std::string(INITIAL_OPKEY) && !isOpkeyDbError && state >= STATE_PARA_LOADED) ||
385         (simState == SimState::SIM_STATE_NOT_PRESENT || simState == SimState::SIM_STATE_NOT_READY ||
386         simState == SimState::SIM_STATE_UNKNOWN)) {
387         AAFwk::Want want;
388         want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_OPERATOR_CONFIG_CHANGED);
389         want.SetParam(KEY_SLOTID, slotId);
390         want.SetParam(CHANGE_STATE, state);
391         std::string eventData(OPERATOR_CONFIG_CHANGED);
392         EventFwk::CommonEventData data;
393         data.SetWant(want);
394         data.SetData(eventData);
395         EventFwk::CommonEventPublishInfo publishInfo;
396         publishInfo.SetOrdered(false);
397         bool publishResult = EventFwk::CommonEventManager::PublishCommonEvent(data, publishInfo, nullptr);
398         TELEPHONY_LOGI("result = %{public}d, opkey: %{public}s, slotId: %{public}d, state: %{public}d",
399             publishResult, opkey.data(), slotId, state);
400         auto simFileManager = simFileManager_.lock();
401         if (simFileManager != nullptr) {
402             TelEventHandler::SendTelEvent(simFileManager, RadioEvent::RADIO_OPERATOR_CONFIG_CHANGED);
403         }
404         return publishResult;
405     }
406     return true;
407 }
408 
IsNeedOperatorLoad(int32_t slotId)409 bool OperatorConfigCache::IsNeedOperatorLoad(int32_t slotId)
410 {
411     std::string opkey = GetOpKey(slotId);
412     TELEPHONY_LOGI("IsNeedOperatorLoad slotId %{public}d opkey %{public}s isLoadingConfig_: %{public}d",
413         slotId, opkey.data(), isLoadingConfig_);
414     if (opkey.empty() || opkey == std::string(INITIAL_OPKEY)) {
415         return true;
416     }
417     if (isLoadingConfig_) {
418         return false;
419     }
420     auto simFileManager = simFileManager_.lock();
421     if (simFileManager == nullptr) {
422         return true;
423     }
424     std::string iccid = Str16ToStr8(simFileManager->GetSimIccId());
425     std::string filename = EncryptIccId(iccid + opkey) + ".json";
426     std::string path = parser_.GetOperatorConfigFilePath(filename);
427     char realPath[PATH_MAX] = { '\0' };
428     if (realpath(path.c_str(), realPath) == nullptr) {
429         TELEPHONY_LOGE("get real path fail");
430         return true;
431     }
432     std::ifstream f(realPath);
433     return !f.good();
434 }
435 
UpdateImsCapFromChip(int32_t slotId,const ImsCapFromChip & imsCapFromChip)436 void OperatorConfigCache::UpdateImsCapFromChip(int32_t slotId, const ImsCapFromChip &imsCapFromChip)
437 {
438     isUpdateImsCapFromChipDone_ = true;
439     OperatorConfig opc;
440     int32_t ret = LoadOperatorConfigFile(slotId, opc);
441     TELEPHONY_LOGI("[slot%{public}d] imsCapFromChip = %{public}d, %{public}d, %{public}d, %{public}d, ret = %{public}d",
442         slotId, imsCapFromChip.volteCap, imsCapFromChip.vowifiCap, imsCapFromChip.vonrCap, imsCapFromChip.vtCap, ret);
443 }
444 
UpdateIccidCache(int32_t state)445 void OperatorConfigCache::UpdateIccidCache(int32_t state)
446 {
447     if (iccidCache_ != "") {
448         return;
449     }
450     auto simFileManager = simFileManager_.lock();
451     if (simFileManager == nullptr) {
452         return;
453     }
454     if (state == STATE_PARA_LOADED || state == STATE_PARA_UPDATE) {
455         iccidCache_ = Str16ToStr8(simFileManager->GetSimIccId());
456     }
457 }
458 
GetSimState(int32_t slotId,SimState & simState)459 int OperatorConfigCache::GetSimState(int32_t slotId, SimState &simState)
460 {
461     if (slotId != slotId_) {
462         TELEPHONY_LOGE("is not current slotId, current slotId %{public}d", slotId_);
463         return TELEPHONY_ERR_ARGUMENT_MISMATCH;
464     }
465     if (simStateManager_ == nullptr) {
466         TELEPHONY_LOGE("simStateManager is nullptr, slotId %{public}d", slotId_);
467         return TELEPHONY_ERR_LOCAL_PTR_NULL;
468     }
469     if (!simStateManager_->HasSimCard()) {
470         simState = SimState::SIM_STATE_NOT_PRESENT;
471         return TELEPHONY_ERR_SUCCESS;
472     }
473     simState = simStateManager_->GetSimState();
474     return TELEPHONY_ERR_SUCCESS;
475 }
476 } // namespace Telephony
477 } // namespace OHOS
478