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