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 <json/json.h>
18 #include <openssl/sha.h>
19 #include <string_ex.h>
20 #include <telephony_types.h>
21
22 #include "common_event_manager.h"
23 #include "common_event_support.h"
24 #include "core_manager_inner.h"
25 #include "radio_event.h"
26 #include "telephony_ext_wrapper.h"
27
28 namespace OHOS {
29 namespace Telephony {
OperatorConfigCache(std::weak_ptr<SimFileManager> simFileManager,int32_t slotId)30 OperatorConfigCache::OperatorConfigCache(std::weak_ptr<SimFileManager> simFileManager, int32_t slotId)
31 : TelEventHandler("OperatorConfigCache"), simFileManager_(simFileManager), slotId_(slotId)
32 {
33 TELEPHONY_LOGI("OperatorConfigCache create");
34 if (TELEPHONY_EXT_WRAPPER.checkOpcVersionIsUpdate_ != nullptr &&
35 TELEPHONY_EXT_WRAPPER.updateOpcVersion_ != nullptr) {
36 if (TELEPHONY_EXT_WRAPPER.checkOpcVersionIsUpdate_()) {
37 ClearAllCache(slotId);
38 TELEPHONY_LOGI("clear all cache done");
39 TELEPHONY_EXT_WRAPPER.updateOpcVersion_();
40 }
41 }
42 }
43
ClearAllCache(int32_t slotId)44 void OperatorConfigCache::ClearAllCache(int32_t slotId)
45 {
46 std::unique_lock<std::mutex> lock(mutex_);
47 ClearOperatorValue(slotId);
48 ClearMemoryCache(slotId);
49 parser_.ClearFilesCache();
50 lock.unlock();
51 }
52
ClearOperatorValue(int32_t slotId)53 void OperatorConfigCache::ClearOperatorValue(int32_t slotId)
54 {
55 auto simFileManager = simFileManager_.lock();
56 if (simFileManager == nullptr) {
57 TELEPHONY_LOGE("simFileManager is nullptr");
58 return;
59 }
60 std::string key;
61 std::string initialOpkey = INITIAL_OPKEY;
62 SetParameter(key.append(OPKEY_PROP_PREFIX).append(std::to_string(slotId)).c_str(), initialOpkey.c_str());
63 simFileManager->SetOpKey("");
64 simFileManager->SetOpName("");
65 simFileManager->SetOpKeyExt("");
66 }
67
ClearMemoryCache(int32_t slotId)68 void OperatorConfigCache::ClearMemoryCache(int32_t slotId)
69 {
70 opc_.stringValue.clear();
71 opc_.stringArrayValue.clear();
72 opc_.intValue.clear();
73 opc_.intArrayValue.clear();
74 opc_.longValue.clear();
75 opc_.longArrayValue.clear();
76 opc_.boolValue.clear();
77 opc_.configValue.clear();
78 }
79
LoadOperatorConfig(int32_t slotId,OperatorConfig & poc)80 int32_t OperatorConfigCache::LoadOperatorConfig(int32_t slotId, OperatorConfig &poc)
81 {
82 auto simFileManager = simFileManager_.lock();
83 if (simFileManager == nullptr) {
84 TELEPHONY_LOGE("simFileManager is nullptr");
85 return TELEPHONY_ERR_LOCAL_PTR_NULL;
86 }
87 std::string iccid = Str16ToStr8(simFileManager->GetSimIccId());
88 std::string filename = EncryptIccId(iccid) + ".json";
89 std::string opkey = GetOpKey(slotId);
90 if (opkey == std::string(INITIAL_OPKEY)) {
91 TELEPHONY_LOGI("load default operator config");
92 filename = DEFAULT_OPERATOR_CONFIG;
93 }
94 SimState simState = SimState::SIM_STATE_UNKNOWN;
95 CoreManagerInner::GetInstance().GetSimState(slotId, simState);
96 TELEPHONY_LOGI("LoadOperatorConfig simState = %{public}d", simState);
97 bool canAnnounceChanged = (simState == SimState::SIM_STATE_NOT_PRESENT || simState == SimState::SIM_STATE_READY);
98 Json::Value opcJson;
99 if (parser_.ParseOperatorConfigFromFile(poc, parser_.GetOperatorConfigFilePath(filename), opcJson)) {
100 TELEPHONY_LOGI("load from file success opc size %{public}zu", poc.configValue.size());
101 if (poc.configValue.size() > 0) {
102 std::unique_lock<std::mutex> lock(mutex_);
103 CopyOperatorConfig(poc, opc_);
104 lock.unlock();
105 if (canAnnounceChanged) {
106 AnnounceOperatorConfigChanged(slotId);
107 }
108 return TELEPHONY_ERR_SUCCESS;
109 }
110 }
111 if (parser_.ParseFromCustomSystem(slotId, poc, opcJson)) {
112 TELEPHONY_LOGI("load from custom system success");
113 parser_.WriteOperatorConfigJson(filename, opcJson);
114
115 if (poc.configValue.size() > 0) {
116 std::unique_lock<std::mutex> lock(mutex_);
117 CopyOperatorConfig(poc, opc_);
118 lock.unlock();
119 if (canAnnounceChanged) {
120 AnnounceOperatorConfigChanged(slotId);
121 }
122 return TELEPHONY_ERR_SUCCESS;
123 }
124 }
125 return CORE_ERR_OPERATOR_CONF_NOT_EXIT;
126 }
127
GetOperatorConfigs(int32_t slotId,OperatorConfig & poc)128 int32_t OperatorConfigCache::GetOperatorConfigs(int32_t slotId, OperatorConfig &poc)
129 {
130 if (opc_.configValue.size() > 0) {
131 TELEPHONY_LOGI("get from memory");
132 std::unique_lock<std::mutex> lock(mutex_);
133 CopyOperatorConfig(opc_, poc);
134 lock.unlock();
135 return TELEPHONY_ERR_SUCCESS;
136 }
137 TELEPHONY_LOGI("reload operator config");
138 return LoadOperatorConfig(slotId, poc);
139 }
140
CopyOperatorConfig(const OperatorConfig & from,OperatorConfig & to)141 void OperatorConfigCache::CopyOperatorConfig(const OperatorConfig &from, OperatorConfig &to)
142 {
143 for (const auto &it : from.configValue) {
144 to.configValue[it.first] = it.second;
145 }
146 for (const auto &it : from.boolValue) {
147 to.boolValue[it.first] = it.second;
148 }
149 for (const auto &it : from.intValue) {
150 to.intValue[it.first] = it.second;
151 }
152 for (const auto &it : from.longValue) {
153 to.longValue[it.first] = it.second;
154 }
155 for (const auto &it : from.stringValue) {
156 to.stringValue[it.first] = it.second;
157 }
158 for (const auto &it : from.intArrayValue) {
159 to.intArrayValue[it.first] = std::vector<int32_t>(it.second);
160 }
161 for (const auto &it : from.longArrayValue) {
162 to.longArrayValue[it.first] = std::vector<int64_t>(it.second);
163 }
164 for (const auto &it : from.stringArrayValue) {
165 to.stringArrayValue[it.first] = std::vector<std::string>(it.second);
166 }
167 }
168
GetOpKey(int32_t slotId)169 std::string OperatorConfigCache::GetOpKey(int32_t slotId)
170 {
171 char simOpKey[SYSPARA_SIZE] = { 0 };
172 std::string key;
173 GetParameter(key.append(OPKEY_PROP_PREFIX).append(std::to_string(slotId)).c_str(), DEFAULT_OPERATOR_KEY,
174 simOpKey, SYSPARA_SIZE);
175 key.shrink_to_fit();
176 return simOpKey;
177 }
178
EncryptIccId(const std::string iccid)179 std::string OperatorConfigCache::EncryptIccId(const std::string iccid)
180 {
181 unsigned char hash[SHA256_DIGEST_LENGTH];
182 SHA256_CTX sha256;
183 SHA256_Init(&sha256);
184 SHA256_Update(&sha256, iccid.c_str(), iccid.size());
185 SHA256_Final(hash, &sha256);
186 std::string encryptIccId = SIMUtils::BytesConvertToHexString(hash, SHA256_DIGEST_LENGTH);
187 return encryptIccId;
188 }
189
RegisterForIccChange()190 bool OperatorConfigCache::RegisterForIccChange()
191 {
192 TELEPHONY_LOGI("OperatorConfigCache::RegisterForIccLoaded");
193 auto simFileManager = simFileManager_.lock();
194 if (simFileManager == nullptr) {
195 TELEPHONY_LOGE("OperatorConfigCache::can not get SimFileManager");
196 return false;
197 }
198 simFileManager->RegisterCoreNotify(shared_from_this(), RadioEvent::RADIO_SIM_STATE_CHANGE);
199 return true;
200 }
201
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)202 void OperatorConfigCache::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
203 {
204 if (event == nullptr) {
205 TELEPHONY_LOGE("start ProcessEvent but event is null!");
206 return;
207 }
208 SimState simState = SimState::SIM_STATE_UNKNOWN;
209 CoreManagerInner::GetInstance().GetSimState(slotId_, simState);
210 if (event->GetInnerEventId() == RadioEvent::RADIO_SIM_STATE_CHANGE) {
211 TELEPHONY_LOGI("OperatorConfigCache::Sim state change");
212 if (simState == SimState::SIM_STATE_NOT_PRESENT || simState == SimState::SIM_STATE_LOCKED) {
213 std::unique_lock<std::mutex> lock(mutex_);
214 ClearOperatorValue(slotId_);
215 ClearMemoryCache(slotId_);
216 lock.unlock();
217 OperatorConfig opc;
218 LoadOperatorConfig(slotId_, opc);
219 }
220 }
221 }
222
UnRegisterForIccChange()223 bool OperatorConfigCache::UnRegisterForIccChange()
224 {
225 TELEPHONY_LOGI("OperatorConfigCache::UnRegisterForIccLoaded");
226 auto simFileManager = simFileManager_.lock();
227 if (simFileManager == nullptr) {
228 TELEPHONY_LOGE("OperatorConfigCache::can not get SimFileManager");
229 return false;
230 }
231 simFileManager->UnRegisterCoreNotify(shared_from_this(), RadioEvent::RADIO_SIM_STATE_CHANGE);
232 return true;
233 }
234
SendSimMatchedOperatorInfo(int32_t slotId)235 void OperatorConfigCache::SendSimMatchedOperatorInfo(int32_t slotId)
236 {
237 TELEPHONY_LOGI("OperatorConfigCache::SendSimMatchedOperatorInfo");
238 auto simFileManager = simFileManager_.lock();
239 if (simFileManager == nullptr) {
240 TELEPHONY_LOGE("OperatorConfigCache::can not get SimFileManager");
241 return;
242 }
243 SimState simState = SimState::SIM_STATE_UNKNOWN;
244 CoreManagerInner::GetInstance().GetSimState(slotId_, simState);
245 std::string operName = Str16ToStr8(simFileManager->GetOpName());
246 std::string operKey = Str16ToStr8(simFileManager->GetOpKey());
247 int32_t response = CoreManagerInner::GetInstance().SendSimMatchedOperatorInfo(slotId,
248 static_cast<int32_t>(simState), operName, operKey);
249 TELEPHONY_LOGI("OperatorConfigCache::SendSimMatchedOperatorInfo response = %{public}d", response);
250 }
251
AnnounceOperatorConfigChanged(int32_t slotId)252 bool OperatorConfigCache::AnnounceOperatorConfigChanged(int32_t slotId)
253 {
254 SendSimMatchedOperatorInfo(slotId);
255 AAFwk::Want want;
256 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_OPERATOR_CONFIG_CHANGED);
257 want.SetParam(KEY_SLOTID, slotId);
258 std::string eventData(OPERATOR_CONFIG_CHANGED);
259 EventFwk::CommonEventData data;
260 data.SetWant(want);
261 data.SetData(eventData);
262 EventFwk::CommonEventPublishInfo publishInfo;
263 publishInfo.SetOrdered(false);
264 bool publishResult = EventFwk::CommonEventManager::PublishCommonEvent(data, publishInfo, nullptr);
265 TELEPHONY_LOGI("OperatorConfigCache:AnnounceOperatorConfigChanged end###result = %{public}d", publishResult);
266 return publishResult;
267 }
268 } // namespace Telephony
269 } // namespace OHOS
270