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