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
29 namespace OHOS {
30 namespace Telephony {
OperatorConfigCache(std::weak_ptr<SimFileManager> simFileManager,int32_t slotId)31 OperatorConfigCache::OperatorConfigCache(std::weak_ptr<SimFileManager> simFileManager, int32_t slotId)
32 : TelEventHandler("OperatorConfigCache"), simFileManager_(simFileManager), slotId_(slotId)
33 {
34 TELEPHONY_LOGI("OperatorConfigCache create");
35 }
36
ClearAllCache(int32_t slotId)37 void OperatorConfigCache::ClearAllCache(int32_t slotId)
38 {
39 std::unique_lock<std::mutex> lock(mutex_);
40 ClearOperatorValue(slotId);
41 ClearMemoryCache(slotId);
42 OperatorFileParser::ClearFilesCache();
43 lock.unlock();
44 }
45
ClearOperatorValue(int32_t slotId)46 void OperatorConfigCache::ClearOperatorValue(int32_t slotId)
47 {
48 auto simFileManager = simFileManager_.lock();
49 if (simFileManager == nullptr) {
50 TELEPHONY_LOGE("simFileManager is nullptr");
51 return;
52 }
53 std::string key;
54 std::string initialOpkey = INITIAL_OPKEY;
55 SetParameter(key.append(OPKEY_PROP_PREFIX).append(std::to_string(slotId)).c_str(), initialOpkey.c_str());
56 simFileManager->SetOpKey("");
57 simFileManager->SetOpName("");
58 simFileManager->SetOpKeyExt("");
59 }
60
ClearMemoryCache(int32_t slotId)61 void OperatorConfigCache::ClearMemoryCache(int32_t slotId)
62 {
63 opc_.stringValue.clear();
64 opc_.stringArrayValue.clear();
65 opc_.intValue.clear();
66 opc_.intArrayValue.clear();
67 opc_.longValue.clear();
68 opc_.longArrayValue.clear();
69 opc_.boolValue.clear();
70 opc_.configValue.clear();
71 }
72
UpdateCurrentOpc(int32_t slotId,OperatorConfig & poc,int32_t state,bool needUpdateLoading)73 void OperatorConfigCache::UpdateCurrentOpc(
74 int32_t slotId, OperatorConfig &poc, int32_t state, bool needUpdateLoading)
75 {
76 std::unique_lock<std::mutex> lock(mutex_);
77 CopyOperatorConfig(poc, opc_);
78 lock.unlock();
79 AnnounceOperatorConfigChanged(slotId, state);
80 if (needUpdateLoading) {
81 isLoadingConfig = false;
82 }
83 }
84
LoadOperatorConfig(int32_t slotId,OperatorConfig & poc,int32_t state)85 int32_t OperatorConfigCache::LoadOperatorConfig(int32_t slotId, OperatorConfig &poc, int32_t state)
86 {
87 auto simFileManager = simFileManager_.lock();
88 if (simFileManager == nullptr) {
89 TELEPHONY_LOGE("simFileManager is nullptr");
90 return TELEPHONY_ERR_LOCAL_PTR_NULL;
91 }
92 std::string iccid = Str16ToStr8(simFileManager->GetSimIccId());
93 std::string opkey = GetOpKey(slotId);
94 std::string filename = EncryptIccId(iccid + opkey) + ".json";
95 if (opkey == std::string(INITIAL_OPKEY)) {
96 TELEPHONY_LOGI("load default operator config");
97 filename = DEFAULT_OPERATOR_CONFIG;
98 }
99 isLoadingConfig = true;
100 SimState simState = SimState::SIM_STATE_UNKNOWN;
101 CoreManagerInner::GetInstance().GetSimState(slotId, simState);
102 TELEPHONY_LOGI("LoadOperatorConfig slotId = %{public}d simState = %{public}d", slotId, simState);
103 cJSON *root = nullptr;
104 if (parser_.ParseOperatorConfigFromFile(poc, parser_.GetOperatorConfigFilePath(filename), root)) {
105 TELEPHONY_LOGI("load from file success opc size %{public}zu", poc.configValue.size());
106 if (poc.configValue.size() > 0) {
107 // state indicate the case of load operator config
108 UpdateCurrentOpc(slotId, poc, state, false);
109 root = nullptr;
110 return TELEPHONY_ERR_SUCCESS;
111 }
112 }
113 root = cJSON_CreateObject();
114 if (parser_.ParseFromCustomSystem(slotId, poc, root)) {
115 TELEPHONY_LOGI("load from custom system success");
116 parser_.WriteOperatorConfigJson(filename, root);
117
118 if (poc.configValue.size() > 0) {
119 // state indicate the case of load operator config
120 UpdateCurrentOpc(slotId, poc, state, true);
121 if (root != nullptr) {
122 cJSON_Delete(root);
123 root = nullptr;
124 }
125 return TELEPHONY_ERR_SUCCESS;
126 }
127 }
128 isLoadingConfig = false;
129 if (root != nullptr) {
130 cJSON_Delete(root);
131 root = nullptr;
132 }
133 return CORE_ERR_OPERATOR_CONF_NOT_EXIT;
134 }
135
GetOperatorConfigs(int32_t slotId,OperatorConfig & poc)136 int32_t OperatorConfigCache::GetOperatorConfigs(int32_t slotId, OperatorConfig &poc)
137 {
138 std::unique_lock<std::mutex> lock(mutex_);
139 if (opc_.configValue.size() > 0) {
140 TELEPHONY_LOGD("get from memory");
141 CopyOperatorConfig(opc_, poc);
142 lock.unlock();
143 return TELEPHONY_ERR_SUCCESS;
144 }
145 lock.unlock();
146 TELEPHONY_LOGI("reload operator config");
147 return LoadOperatorConfig(slotId, poc);
148 }
149
UpdateOperatorConfigs(int32_t slotId)150 int32_t OperatorConfigCache::UpdateOperatorConfigs(int32_t slotId)
151 {
152 std::unique_lock<std::mutex> lock(mutex_);
153 ClearMemoryCache(slotId);
154 lock.unlock();
155 if (slotId == 0) {
156 TELEPHONY_LOGD("OperatorConfigCache:UpdateOperatorConfigs ClearFilesCache");
157 OperatorFileParser::ClearFilesCache();
158 }
159 OperatorConfig opc;
160 int32_t ret = LoadOperatorConfig(slotId_, opc, STATE_PARA_UPDATE);
161 return ret;
162 }
163
CopyOperatorConfig(const OperatorConfig & from,OperatorConfig & to)164 void OperatorConfigCache::CopyOperatorConfig(const OperatorConfig &from, OperatorConfig &to)
165 {
166 for (const auto &it : from.configValue) {
167 to.configValue[it.first] = it.second;
168 }
169 for (const auto &it : from.boolValue) {
170 to.boolValue[it.first] = it.second;
171 }
172 for (const auto &it : from.intValue) {
173 to.intValue[it.first] = it.second;
174 }
175 for (const auto &it : from.longValue) {
176 to.longValue[it.first] = it.second;
177 }
178 for (const auto &it : from.stringValue) {
179 to.stringValue[it.first] = it.second;
180 }
181 for (const auto &it : from.intArrayValue) {
182 to.intArrayValue[it.first] = std::vector<int32_t>(it.second);
183 }
184 for (const auto &it : from.longArrayValue) {
185 to.longArrayValue[it.first] = std::vector<int64_t>(it.second);
186 }
187 for (const auto &it : from.stringArrayValue) {
188 to.stringArrayValue[it.first] = std::vector<std::string>(it.second);
189 }
190 }
191
GetOpKey(int32_t slotId)192 std::string OperatorConfigCache::GetOpKey(int32_t slotId)
193 {
194 char simOpKey[SYSPARA_SIZE] = { 0 };
195 std::string key;
196 GetParameter(key.append(OPKEY_PROP_PREFIX).append(std::to_string(slotId)).c_str(), DEFAULT_OPERATOR_KEY,
197 simOpKey, SYSPARA_SIZE);
198 key.shrink_to_fit();
199 return simOpKey;
200 }
201
EncryptIccId(const std::string iccid)202 std::string OperatorConfigCache::EncryptIccId(const std::string iccid)
203 {
204 unsigned char hash[SHA256_DIGEST_LENGTH];
205 SHA256_CTX sha256;
206 SHA256_Init(&sha256);
207 SHA256_Update(&sha256, iccid.c_str(), iccid.size());
208 SHA256_Final(hash, &sha256);
209 std::string encryptIccId = SIMUtils::BytesConvertToHexString(hash, SHA256_DIGEST_LENGTH);
210 return encryptIccId;
211 }
212
RegisterForIccChange()213 bool OperatorConfigCache::RegisterForIccChange()
214 {
215 TELEPHONY_LOGI("OperatorConfigCache::RegisterForIccLoaded");
216 auto simFileManager = simFileManager_.lock();
217 if (simFileManager == nullptr) {
218 TELEPHONY_LOGE("OperatorConfigCache::can not get SimFileManager");
219 return false;
220 }
221 simFileManager->RegisterCoreNotify(shared_from_this(), RadioEvent::RADIO_SIM_STATE_CHANGE);
222 return true;
223 }
224
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)225 void OperatorConfigCache::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
226 {
227 if (event == nullptr) {
228 TELEPHONY_LOGE("start ProcessEvent but event is null!");
229 return;
230 }
231 SimState simState = SimState::SIM_STATE_UNKNOWN;
232 CoreManagerInner::GetInstance().GetSimState(slotId_, simState);
233 if (event->GetInnerEventId() == RadioEvent::RADIO_SIM_STATE_CHANGE) {
234 TELEPHONY_LOGI("OperatorConfigCache::Sim state change");
235 if (simState == SimState::SIM_STATE_NOT_PRESENT || simState == SimState::SIM_STATE_LOCKED) {
236 std::unique_lock<std::mutex> lock(mutex_);
237 ClearOperatorValue(slotId_);
238 ClearMemoryCache(slotId_);
239 lock.unlock();
240 OperatorConfig opc;
241 LoadOperatorConfig(slotId_, opc);
242 }
243 }
244 }
245
UnRegisterForIccChange()246 bool OperatorConfigCache::UnRegisterForIccChange()
247 {
248 TELEPHONY_LOGI("OperatorConfigCache::UnRegisterForIccLoaded");
249 auto simFileManager = simFileManager_.lock();
250 if (simFileManager == nullptr) {
251 TELEPHONY_LOGE("OperatorConfigCache::can not get SimFileManager");
252 return false;
253 }
254 simFileManager->UnRegisterCoreNotify(shared_from_this(), RadioEvent::RADIO_SIM_STATE_CHANGE);
255 return true;
256 }
257
SendSimMatchedOperatorInfo(int32_t slotId)258 void OperatorConfigCache::SendSimMatchedOperatorInfo(int32_t slotId)
259 {
260 TELEPHONY_LOGI("OperatorConfigCache::SendSimMatchedOperatorInfo");
261 auto simFileManager = simFileManager_.lock();
262 if (simFileManager == nullptr) {
263 TELEPHONY_LOGE("OperatorConfigCache::can not get SimFileManager");
264 return;
265 }
266 SimState simState = SimState::SIM_STATE_UNKNOWN;
267 CoreManagerInner::GetInstance().GetSimState(slotId_, simState);
268 std::string operName = Str16ToStr8(simFileManager->GetOpName());
269 std::string operKey = Str16ToStr8(simFileManager->GetOpKey());
270 std::string operNameNew = (operKey == "") ? "NULL" : operName;
271 int32_t response = CoreManagerInner::GetInstance().SendSimMatchedOperatorInfo(slotId,
272 static_cast<int32_t>(simState), operNameNew, operKey);
273 TELEPHONY_LOGI("OperatorConfigCache::SendSimMatchedOperatorInfo response = %{public}d", response);
274 }
275
notifyInitApnConfigs(int32_t slotId)276 void OperatorConfigCache::notifyInitApnConfigs(int32_t slotId)
277 {
278 SimState simState = SimState::SIM_STATE_UNKNOWN;
279 CoreManagerInner::GetInstance().GetSimState(slotId, simState);
280 if (!(simState == SimState::SIM_STATE_READY || simState == SimState::SIM_STATE_LOADED)) {
281 return;
282 }
283 auto helper = PdpProfileRdbHelper::GetInstance();
284 if (helper == nullptr) {
285 TELEPHONY_LOGE("get PdpProfileRdbHelper Failed.");
286 return;
287 }
288 TELEPHONY_LOGI("OperatorConfigCache:notifyInitApnConfigs end");
289 helper->notifyInitApnConfigs(slotId);
290 }
291
AnnounceOperatorConfigChanged(int32_t slotId,int32_t state)292 bool OperatorConfigCache::AnnounceOperatorConfigChanged(int32_t slotId, int32_t state)
293 {
294 notifyInitApnConfigs(slotId);
295 SendSimMatchedOperatorInfo(slotId);
296 AAFwk::Want want;
297 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_OPERATOR_CONFIG_CHANGED);
298 want.SetParam(KEY_SLOTID, slotId);
299 want.SetParam(CHANGE_STATE, state);
300 std::string eventData(OPERATOR_CONFIG_CHANGED);
301 EventFwk::CommonEventData data;
302 data.SetWant(want);
303 data.SetData(eventData);
304 EventFwk::CommonEventPublishInfo publishInfo;
305 publishInfo.SetOrdered(false);
306 bool publishResult = EventFwk::CommonEventManager::PublishCommonEvent(data, publishInfo, nullptr);
307 TELEPHONY_LOGI("OperatorConfigCache:AnnounceOperatorConfigChanged end###result = %{public}d", publishResult);
308 return publishResult;
309 }
310
IsNeedOperatorLoad(int32_t slotId)311 bool OperatorConfigCache::IsNeedOperatorLoad(int32_t slotId)
312 {
313 std::string opkey = GetOpKey(slotId);
314 TELEPHONY_LOGI("IsNeedOperatorLoad slotId %{public}d opkey %{public}s isLoadingConfig: %{public}d",
315 slotId, opkey.data(), isLoadingConfig);
316 if (opkey.empty() || opkey == std::string(INITIAL_OPKEY)) {
317 return true;
318 }
319 if (isLoadingConfig) {
320 return false;
321 }
322 auto simFileManager = simFileManager_.lock();
323 if (simFileManager == nullptr) {
324 TELEPHONY_LOGI("simFileManager is nullptr");
325 return true;
326 }
327 std::string iccid = Str16ToStr8(simFileManager->GetSimIccId());
328 std::string filename = EncryptIccId(iccid) + ".json";
329 std::string path = parser_.GetOperatorConfigFilePath(filename);
330 std::ifstream f(path.c_str());
331 return !f.good();
332 }
333 } // namespace Telephony
334 } // namespace OHOS
335