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