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